

20241230 하관우 back-end 최초커밋
@317bb2bb44d9f34e4134388d39b860b7f6b13c49
+++ .gitignore
... | ... | @@ -0,0 +1,39 @@ |
1 | +HELP.md | |
2 | +.gradle | |
3 | +build/ | |
4 | +!gradle/wrapper/gradle-wrapper.jar | |
5 | +!**/src/main/**/build/ | |
6 | +!**/src/test/**/build/ | |
7 | + | |
8 | +### STS ### | |
9 | +.apt_generated | |
10 | +.classpath | |
11 | +.factorypath | |
12 | +.project | |
13 | +.settings | |
14 | +.springBeans | |
15 | +.sts4-cache | |
16 | +bin/ | |
17 | +!**/src/main/**/bin/ | |
18 | +!**/src/test/**/bin/ | |
19 | + | |
20 | +### IntelliJ IDEA ### | |
21 | +.idea | |
22 | +*.iws | |
23 | +*.iml | |
24 | +*.ipr | |
25 | +out/ | |
26 | +!**/src/main/**/out/ | |
27 | +!**/src/test/**/out/ | |
28 | + | |
29 | +### NetBeans ### | |
30 | +/nbproject/private/ | |
31 | +/nbbuild/ | |
32 | +/dist/ | |
33 | +/nbdist/ | |
34 | +/.nb-gradle/ | |
35 | + | |
36 | +### VS Code ### | |
37 | +.vscode/ | |
38 | + | |
39 | +/logs/ |
+++ build.gradle
... | ... | @@ -0,0 +1,112 @@ |
1 | +plugins { | |
2 | + id 'java' | |
3 | + id 'org.springframework.boot' version '3.2.1' | |
4 | + id 'io.spring.dependency-management' version '1.1.4' | |
5 | +} | |
6 | + | |
7 | +group = 'com.takensoft' | |
8 | +version = '0.0.1-SNAPSHOT' | |
9 | +apply plugin:'war' | |
10 | + | |
11 | +java { | |
12 | + sourceCompatibility = '17' | |
13 | +} | |
14 | + | |
15 | +repositories { | |
16 | + mavenCentral() | |
17 | +} | |
18 | + | |
19 | +dependencies { | |
20 | + | |
21 | + // postgresql jdbc | |
22 | + implementation group: 'org.postgresql', name: 'postgresql', version: '42.6.0' | |
23 | + // 오라클 jdbc | |
24 | + implementation group: 'com.oracle.database.jdbc', name: 'ojdbc11', version: '21.8.0.0' | |
25 | + // 마리아 jdbc | |
26 | + implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '3.3.2' | |
27 | + // mysql jdbc | |
28 | + implementation group: 'com.mysql', name: 'mysql-connector-j', version: '8.0.33' | |
29 | + // mssql jdbc | |
30 | + implementation group: 'com.microsoft.sqlserver', name: 'mssql-jdbc', version: '12.4.2.jre11' | |
31 | + | |
32 | + // cron-utils 라이브러리 추가 | |
33 | + implementation 'com.cronutils:cron-utils:9.1.3' | |
34 | + // mybatis | |
35 | + implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3' | |
36 | + | |
37 | + // sftp | |
38 | + implementation 'com.jcraft:jsch:0.1.55' | |
39 | + | |
40 | + //lombok 라이브러리 | |
41 | + compileOnly 'org.projectlombok:lombok' | |
42 | + annotationProcessor 'org.projectlombok:lombok' | |
43 | + testCompileOnly 'org.projectlombok:lombok' | |
44 | + testAnnotationProcessor 'org.projectlombok:lombok' | |
45 | + | |
46 | + // https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple | |
47 | + implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' | |
48 | + // https://mvnrepository.com/artifact/org.json/json | |
49 | + implementation group: 'org.json', name: 'json', version: '20231013' | |
50 | + // https://mvnrepository.com/artifact/org.springframework.security/spring-security-crypto | |
51 | + implementation group: 'org.springframework.security', name: 'spring-security-crypto', version: '6.2.1' | |
52 | + // https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api | |
53 | + //compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1' | |
54 | + implementation 'org.springframework.boot:spring-boot-starter' | |
55 | + implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16' | |
56 | + // Log4j2 스타터 | |
57 | + implementation 'org.springframework.boot:spring-boot-starter-log4j2' | |
58 | + // https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-jsr310 | |
59 | + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310' | |
60 | + | |
61 | + // 웹 푸시 라이브러리 | |
62 | + implementation group: 'nl.martijndwars', name: 'web-push', version: '5.1.1' | |
63 | + implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.70' | |
64 | + | |
65 | + //poi | |
66 | + implementation 'org.apache.poi:poi:5.2.5' | |
67 | + implementation 'org.apache.poi:poi-ooxml:5.2.5' | |
68 | + | |
69 | + // Super CSV 라이브러리 추가 | |
70 | + implementation 'net.sf.supercsv:super-csv:2.4.0' | |
71 | + //Open CSV 라이브러리 추가 | |
72 | + implementation group: 'com.opencsv', name: 'opencsv', version: '5.5.2' | |
73 | + | |
74 | + // 기본 | |
75 | + implementation 'org.springframework.boot:spring-boot-starter-web' | |
76 | + testImplementation 'org.springframework.boot:spring-boot-starter-test' | |
77 | + | |
78 | + // API 게이트 웨이 | |
79 | + implementation files('libs/apim-gateway-auth-1.1.jar') | |
80 | + | |
81 | + // 새올 추가 | |
82 | + implementation files('libs/commons-beanutils-1.8.3.jar') | |
83 | + implementation files('libs/commons-collections-3.2.1.jar') | |
84 | + implementation files('libs/commons-lang-2.5.jar') | |
85 | + implementation files('libs/commons-logging-1.1.1.jar') | |
86 | + implementation files('libs/crypto.jar') | |
87 | + implementation files('libs/ezmorph-1.0.2.jar') | |
88 | + implementation files('libs/httpclient-4.3.5.jar') | |
89 | + implementation files('libs/httpcore-4.3.2.jar') | |
90 | + implementation files('libs/json-lib-2.4-jdk15.jar') | |
91 | + | |
92 | + | |
93 | + providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' | |
94 | + | |
95 | + // 지원되지 않은 오라클 DB 문자 집합 문제 해결용 | |
96 | + implementation group: 'com.oracle.ojdbc', name: 'orai18n', version: '19.3.0.0' | |
97 | +} | |
98 | + | |
99 | +configurations { | |
100 | + all { | |
101 | + exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' | |
102 | + } | |
103 | +} | |
104 | + | |
105 | +tasks.named('test') { | |
106 | + useJUnitPlatform() | |
107 | +} | |
108 | + | |
109 | +bootJar{ | |
110 | + archiveBaseName="takenbimanager" | |
111 | + archiveVersion=version | |
112 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ gradle/wrapper/gradle-wrapper.jar
Binary file is not shown |
+++ gradle/wrapper/gradle-wrapper.properties
... | ... | @@ -0,0 +1,6 @@ |
1 | +#Wed Dec 27 17:54:29 KST 2023 | |
2 | +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip | |
3 | +distributionBase=GRADLE_USER_HOME | |
4 | +distributionPath=wrapper/dists | |
5 | +zipStorePath=wrapper/dists | |
6 | +zipStoreBase=GRADLE_USER_HOME |
+++ gradlew
... | ... | @@ -0,0 +1,249 @@ |
1 | +#!/bin/sh | |
2 | + | |
3 | +# | |
4 | +# Copyright © 2015-2021 the original authors. | |
5 | +# | |
6 | +# Licensed under the Apache License, Version 2.0 (the "License"); | |
7 | +# you may not use this file except in compliance with the License. | |
8 | +# You may obtain a copy of the License at | |
9 | +# | |
10 | +# https://www.apache.org/licenses/LICENSE-2.0 | |
11 | +# | |
12 | +# Unless required by applicable law or agreed to in writing, software | |
13 | +# distributed under the License is distributed on an "AS IS" BASIS, | |
14 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
15 | +# See the License for the specific language governing permissions and | |
16 | +# limitations under the License. | |
17 | +# | |
18 | + | |
19 | +############################################################################## | |
20 | +# | |
21 | +# Gradle start up script for POSIX generated by Gradle. | |
22 | +# | |
23 | +# Important for running: | |
24 | +# | |
25 | +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is | |
26 | +# noncompliant, but you have some other compliant shell such as ksh or | |
27 | +# bash, then to run this script, type that shell name before the whole | |
28 | +# command line, like: | |
29 | +# | |
30 | +# ksh Gradle | |
31 | +# | |
32 | +# Busybox and similar reduced shells will NOT work, because this script | |
33 | +# requires all of these POSIX shell features: | |
34 | +# * functions; | |
35 | +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», | |
36 | +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; | |
37 | +# * compound commands having a testable exit status, especially «case»; | |
38 | +# * various built-in commands including «command», «set», and «ulimit». | |
39 | +# | |
40 | +# Important for patching: | |
41 | +# | |
42 | +# (2) This script targets any POSIX shell, so it avoids extensions provided | |
43 | +# by Bash, Ksh, etc; in particular arrays are avoided. | |
44 | +# | |
45 | +# The "traditional" practice of packing multiple parameters into a | |
46 | +# space-separated string is a well documented source of bugs and security | |
47 | +# problems, so this is (mostly) avoided, by progressively accumulating | |
48 | +# options in "$@", and eventually passing that to Java. | |
49 | +# | |
50 | +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, | |
51 | +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; | |
52 | +# see the in-line comments for details. | |
53 | +# | |
54 | +# There are tweaks for specific operating systems such as AIX, CygWin, | |
55 | +# Darwin, MinGW, and NonStop. | |
56 | +# | |
57 | +# (3) This script is generated from the Groovy template | |
58 | +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | |
59 | +# within the Gradle project. | |
60 | +# | |
61 | +# You can find Gradle at https://github.com/gradle/gradle/. | |
62 | +# | |
63 | +############################################################################## | |
64 | + | |
65 | +# Attempt to set APP_HOME | |
66 | + | |
67 | +# Resolve links: $0 may be a link | |
68 | +app_path=$0 | |
69 | + | |
70 | +# Need this for daisy-chained symlinks. | |
71 | +while | |
72 | + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path | |
73 | + [ -h "$app_path" ] | |
74 | +do | |
75 | + ls=$( ls -ld "$app_path" ) | |
76 | + link=${ls#*' -> '} | |
77 | + case $link in #( | |
78 | + /*) app_path=$link ;; #( | |
79 | + *) app_path=$APP_HOME$link ;; | |
80 | + esac | |
81 | +done | |
82 | + | |
83 | +# This is normally unused | |
84 | +# shellcheck disable=SC2034 | |
85 | +APP_BASE_NAME=${0##*/} | |
86 | +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) | |
87 | +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit | |
88 | + | |
89 | +# Use the maximum available, or set MAX_FD != -1 to use that value. | |
90 | +MAX_FD=maximum | |
91 | + | |
92 | +warn () { | |
93 | + echo "$*" | |
94 | +} >&2 | |
95 | + | |
96 | +die () { | |
97 | + echo | |
98 | + echo "$*" | |
99 | + echo | |
100 | + exit 1 | |
101 | +} >&2 | |
102 | + | |
103 | +# OS specific support (must be 'true' or 'false'). | |
104 | +cygwin=false | |
105 | +msys=false | |
106 | +darwin=false | |
107 | +nonstop=false | |
108 | +case "$( uname )" in #( | |
109 | + CYGWIN* ) cygwin=true ;; #( | |
110 | + Darwin* ) darwin=true ;; #( | |
111 | + MSYS* | MINGW* ) msys=true ;; #( | |
112 | + NONSTOP* ) nonstop=true ;; | |
113 | +esac | |
114 | + | |
115 | +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | |
116 | + | |
117 | + | |
118 | +# Determine the Java command to use to start the JVM. | |
119 | +if [ -n "$JAVA_HOME" ] ; then | |
120 | + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | |
121 | + # IBM's JDK on AIX uses strange locations for the executables | |
122 | + JAVACMD=$JAVA_HOME/jre/sh/java | |
123 | + else | |
124 | + JAVACMD=$JAVA_HOME/bin/java | |
125 | + fi | |
126 | + if [ ! -x "$JAVACMD" ] ; then | |
127 | + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | |
128 | + | |
129 | +Please set the JAVA_HOME variable in your environment to match the | |
130 | +location of your Java installation." | |
131 | + fi | |
132 | +else | |
133 | + JAVACMD=java | |
134 | + if ! command -v java >/dev/null 2>&1 | |
135 | + then | |
136 | + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | |
137 | + | |
138 | +Please set the JAVA_HOME variable in your environment to match the | |
139 | +location of your Java installation." | |
140 | + fi | |
141 | +fi | |
142 | + | |
143 | +# Increase the maximum file descriptors if we can. | |
144 | +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | |
145 | + case $MAX_FD in #( | |
146 | + max*) | |
147 | + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. | |
148 | + # shellcheck disable=SC2039,SC3045 | |
149 | + MAX_FD=$( ulimit -H -n ) || | |
150 | + warn "Could not query maximum file descriptor limit" | |
151 | + esac | |
152 | + case $MAX_FD in #( | |
153 | + '' | soft) :;; #( | |
154 | + *) | |
155 | + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. | |
156 | + # shellcheck disable=SC2039,SC3045 | |
157 | + ulimit -n "$MAX_FD" || | |
158 | + warn "Could not set maximum file descriptor limit to $MAX_FD" | |
159 | + esac | |
160 | +fi | |
161 | + | |
162 | +# Collect all arguments for the java command, stacking in reverse order: | |
163 | +# * args from the command line | |
164 | +# * the main class name | |
165 | +# * -classpath | |
166 | +# * -D...appname settings | |
167 | +# * --module-path (only if needed) | |
168 | +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. | |
169 | + | |
170 | +# For Cygwin or MSYS, switch paths to Windows format before running java | |
171 | +if "$cygwin" || "$msys" ; then | |
172 | + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) | |
173 | + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) | |
174 | + | |
175 | + JAVACMD=$( cygpath --unix "$JAVACMD" ) | |
176 | + | |
177 | + # Now convert the arguments - kludge to limit ourselves to /bin/sh | |
178 | + for arg do | |
179 | + if | |
180 | + case $arg in #( | |
181 | + -*) false ;; # don't mess with options #( | |
182 | + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath | |
183 | + [ -e "$t" ] ;; #( | |
184 | + *) false ;; | |
185 | + esac | |
186 | + then | |
187 | + arg=$( cygpath --path --ignore --mixed "$arg" ) | |
188 | + fi | |
189 | + # Roll the args list around exactly as many times as the number of | |
190 | + # args, so each arg winds up back in the position where it started, but | |
191 | + # possibly modified. | |
192 | + # | |
193 | + # NB: a `for` loop captures its iteration list before it begins, so | |
194 | + # changing the positional parameters here affects neither the number of | |
195 | + # iterations, nor the values presented in `arg`. | |
196 | + shift # remove old arg | |
197 | + set -- "$@" "$arg" # push replacement arg | |
198 | + done | |
199 | +fi | |
200 | + | |
201 | + | |
202 | +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |
203 | +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | |
204 | + | |
205 | +# Collect all arguments for the java command: | |
206 | +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, | |
207 | +# and any embedded shellness will be escaped. | |
208 | +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be | |
209 | +# treated as '${Hostname}' itself on the command line. | |
210 | + | |
211 | +set -- \ | |
212 | + "-Dorg.gradle.appname=$APP_BASE_NAME" \ | |
213 | + -classpath "$CLASSPATH" \ | |
214 | + org.gradle.wrapper.GradleWrapperMain \ | |
215 | + "$@" | |
216 | + | |
217 | +# Stop when "xargs" is not available. | |
218 | +if ! command -v xargs >/dev/null 2>&1 | |
219 | +then | |
220 | + die "xargs is not available" | |
221 | +fi | |
222 | + | |
223 | +# Use "xargs" to parse quoted args. | |
224 | +# | |
225 | +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. | |
226 | +# | |
227 | +# In Bash we could simply go: | |
228 | +# | |
229 | +# readarray ARGS < <( xargs -n1 <<<"$var" ) && | |
230 | +# set -- "${ARGS[@]}" "$@" | |
231 | +# | |
232 | +# but POSIX shell has neither arrays nor command substitution, so instead we | |
233 | +# post-process each arg (as a line of input to sed) to backslash-escape any | |
234 | +# character that might be a shell metacharacter, then use eval to reverse | |
235 | +# that process (while maintaining the separation between arguments), and wrap | |
236 | +# the whole thing up as a single "set" statement. | |
237 | +# | |
238 | +# This will of course break if any of these variables contains a newline or | |
239 | +# an unmatched quote. | |
240 | +# | |
241 | + | |
242 | +eval "set -- $( | |
243 | + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | | |
244 | + xargs -n1 | | |
245 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | | |
246 | + tr '\n' ' ' | |
247 | + )" '"$@"' | |
248 | + | |
249 | +exec "$JAVACMD" "$@" |
+++ gradlew.bat
... | ... | @@ -0,0 +1,92 @@ |
1 | +@rem | |
2 | +@rem Copyright 2015 the original author or authors. | |
3 | +@rem | |
4 | +@rem Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | +@rem you may not use this file except in compliance with the License. | |
6 | +@rem You may obtain a copy of the License at | |
7 | +@rem | |
8 | +@rem https://www.apache.org/licenses/LICENSE-2.0 | |
9 | +@rem | |
10 | +@rem Unless required by applicable law or agreed to in writing, software | |
11 | +@rem distributed under the License is distributed on an "AS IS" BASIS, | |
12 | +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | +@rem See the License for the specific language governing permissions and | |
14 | +@rem limitations under the License. | |
15 | +@rem | |
16 | + | |
17 | +@if "%DEBUG%"=="" @echo off | |
18 | +@rem ########################################################################## | |
19 | +@rem | |
20 | +@rem Gradle startup script for Windows | |
21 | +@rem | |
22 | +@rem ########################################################################## | |
23 | + | |
24 | +@rem Set local scope for the variables with windows NT shell | |
25 | +if "%OS%"=="Windows_NT" setlocal | |
26 | + | |
27 | +set DIRNAME=%~dp0 | |
28 | +if "%DIRNAME%"=="" set DIRNAME=. | |
29 | +@rem This is normally unused | |
30 | +set APP_BASE_NAME=%~n0 | |
31 | +set APP_HOME=%DIRNAME% | |
32 | + | |
33 | +@rem Resolve any "." and ".." in APP_HOME to make it shorter. | |
34 | +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi | |
35 | + | |
36 | +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |
37 | +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" | |
38 | + | |
39 | +@rem Find java.exe | |
40 | +if defined JAVA_HOME goto findJavaFromJavaHome | |
41 | + | |
42 | +set JAVA_EXE=java.exe | |
43 | +%JAVA_EXE% -version >NUL 2>&1 | |
44 | +if %ERRORLEVEL% equ 0 goto execute | |
45 | + | |
46 | +echo. | |
47 | +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | |
48 | +echo. | |
49 | +echo Please set the JAVA_HOME variable in your environment to match the | |
50 | +echo location of your Java installation. | |
51 | + | |
52 | +goto fail | |
53 | + | |
54 | +:findJavaFromJavaHome | |
55 | +set JAVA_HOME=%JAVA_HOME:"=% | |
56 | +set JAVA_EXE=%JAVA_HOME%/bin/java.exe | |
57 | + | |
58 | +if exist "%JAVA_EXE%" goto execute | |
59 | + | |
60 | +echo. | |
61 | +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | |
62 | +echo. | |
63 | +echo Please set the JAVA_HOME variable in your environment to match the | |
64 | +echo location of your Java installation. | |
65 | + | |
66 | +goto fail | |
67 | + | |
68 | +:execute | |
69 | +@rem Setup the command line | |
70 | + | |
71 | +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | |
72 | + | |
73 | + | |
74 | +@rem Execute Gradle | |
75 | +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* | |
76 | + | |
77 | +:end | |
78 | +@rem End local scope for the variables with windows NT shell | |
79 | +if %ERRORLEVEL% equ 0 goto mainEnd | |
80 | + | |
81 | +:fail | |
82 | +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | |
83 | +rem the _cmd.exe /c_ return code! | |
84 | +set EXIT_CODE=%ERRORLEVEL% | |
85 | +if %EXIT_CODE% equ 0 set EXIT_CODE=1 | |
86 | +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% | |
87 | +exit /b %EXIT_CODE% | |
88 | + | |
89 | +:mainEnd | |
90 | +if "%OS%"=="Windows_NT" endlocal | |
91 | + | |
92 | +:omega |
+++ libs/apim-gateway-auth-1.1.jar
Binary file is not shown |
+++ libs/commons-beanutils-1.8.3.jar
Binary file is not shown |
+++ libs/commons-collections-3.2.1.jar
Binary file is not shown |
+++ libs/commons-lang-2.5.jar
Binary file is not shown |
+++ libs/commons-logging-1.1.1.jar
Binary file is not shown |
+++ libs/crypto.jar
Binary file is not shown |
+++ libs/ezmorph-1.0.2.jar
Binary file is not shown |
+++ libs/httpclient-4.3.5.jar
Binary file is not shown |
+++ libs/httpcore-4.3.2.jar
Binary file is not shown |
+++ libs/json-lib-2.4-jdk15.jar
Binary file is not shown |
+++ settings.gradle
... | ... | @@ -0,0 +1,1 @@ |
1 | +rootProject.name = 'taken_bi_manager' |
+++ src/main/java/com/takensoft/taken_bi_manager/DBConnectTest.java
... | ... | @@ -0,0 +1,54 @@ |
1 | +package com.takensoft.taken_bi_manager; | |
2 | + | |
3 | +import java.text.SimpleDateFormat; | |
4 | +import java.util.Calendar; | |
5 | +import java.util.LinkedHashMap; | |
6 | +import java.util.List; | |
7 | + | |
8 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionUtil; | |
9 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DataTypeUtil; | |
10 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
11 | +import com.takensoft.taken_bi_manager.common.vo.CheckMessage; | |
12 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType; | |
13 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
14 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
15 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
16 | + | |
17 | +public class DBConnectTest { | |
18 | + public static void main(String[] args) throws Exception { | |
19 | + | |
20 | + try { | |
21 | + Calendar cal = Calendar.getInstance(); | |
22 | + | |
23 | + | |
24 | + SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmm"); | |
25 | + | |
26 | + cal.add(12, -10); | |
27 | + | |
28 | + int i = 0; | |
29 | + | |
30 | + | |
31 | + while (i <= 20) { | |
32 | + cal.add(12, 1); | |
33 | + String keyTime = df.format(cal.getTime()); | |
34 | + | |
35 | + | |
36 | + ++i; | |
37 | + | |
38 | + if(i == 10){ | |
39 | + int s = 0/0; | |
40 | + } | |
41 | + } | |
42 | + | |
43 | + | |
44 | + | |
45 | + }catch (Exception e){ | |
46 | + | |
47 | + | |
48 | + } | |
49 | + | |
50 | + | |
51 | + | |
52 | + | |
53 | + } | |
54 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/MemberSelectTest.java
... | ... | @@ -0,0 +1,60 @@ |
1 | +package com.takensoft.taken_bi_manager; | |
2 | + | |
3 | + | |
4 | +import java.text.SimpleDateFormat; | |
5 | +import java.util.Date; | |
6 | +import java.util.List; | |
7 | +import java.util.Map; | |
8 | +import java.util.UUID; | |
9 | + | |
10 | +import com.takensoft.taken_bi_manager.common.connection.api.util.ApiUtil; | |
11 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ApiParam; | |
12 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi; | |
13 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
14 | +import com.takensoft.taken_bi_manager.data.util.DataTableConvert; | |
15 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
16 | + | |
17 | + | |
18 | +public class MemberSelectTest { | |
19 | + | |
20 | + public static void main(String[] args) throws Exception { | |
21 | + | |
22 | + DataTable dt = new DataTable(); | |
23 | + | |
24 | + ConnectionApi ca = new ConnectionApi(); | |
25 | + ca.setUrl("http://61.82.138.90:10971/aiSafetyCrossing/requestLogInfo.json"); | |
26 | + ca.setType(1); | |
27 | + ca.setRequestType(1); | |
28 | + ca.setDepth("resultData>"); | |
29 | + ApiParam apiParam1 = new ApiParam(); | |
30 | + apiParam1.setKey("st_dt"); | |
31 | + apiParam1.setValue("yyyy-MM-dd 10:22:00"); | |
32 | + apiParam1.setDateForm(true); | |
33 | +// apiParam1.setDateType("month"); | |
34 | + apiParam1.setAddMonth(0); | |
35 | + ca.getParams().add(apiParam1); | |
36 | + ApiParam apiParam2 = new ApiParam(); | |
37 | + apiParam2.setKey("ed_dt"); | |
38 | + apiParam2.setValue("yyyy-MM-dd 10:24:00"); | |
39 | + apiParam2.setDateForm(true); | |
40 | +// apiParam2.setDateType("month"); | |
41 | + apiParam2.setAddMonth(0); | |
42 | + ca.getParams().add(apiParam2); | |
43 | + ApiParam apiParam3 = new ApiParam(); | |
44 | + apiParam3.setKey("apiKey"); | |
45 | + apiParam3.setValue("f66b623060d0f20fee9663b8c0e445dc882cbf4ec4543630abd16c7960be7012"); | |
46 | + ca.getParams().add(apiParam3); | |
47 | + | |
48 | + List<Map<String,Object>> data = ApiUtil.getApiDataList(ApiUtil.apiRequest(ca)); | |
49 | + | |
50 | + dt = DataTableConvert.listMaptoDataset(data); | |
51 | + | |
52 | + int co = 0; | |
53 | + for(List<Object> temp: dt.getRowData()) { | |
54 | + | |
55 | + if(co == 9 ) co = 0; | |
56 | + } | |
57 | + | |
58 | + | |
59 | + } | |
60 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/TakenBiManagerApplication.java
... | ... | @@ -0,0 +1,47 @@ |
1 | +package com.takensoft.taken_bi_manager; | |
2 | + | |
3 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
4 | +import com.fasterxml.jackson.databind.SerializationFeature; | |
5 | +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; | |
6 | +import org.springframework.boot.SpringApplication; | |
7 | +import org.springframework.boot.autoconfigure.SpringBootApplication; | |
8 | +import org.springframework.context.annotation.Bean; | |
9 | +import org.springframework.scheduling.annotation.EnableScheduling; | |
10 | +import org.springframework.web.servlet.view.json.MappingJackson2JsonView; | |
11 | + | |
12 | +import java.text.SimpleDateFormat; | |
13 | +import java.util.TimeZone; | |
14 | + | |
15 | +@SpringBootApplication | |
16 | +@EnableScheduling | |
17 | +class TakenBiManagerApplication { | |
18 | + | |
19 | + public static void main(String[] args) { | |
20 | + SpringApplication.run(TakenBiManagerApplication.class, args); | |
21 | + } | |
22 | + | |
23 | + @Bean(name="jsonView") | |
24 | + public MappingJackson2JsonView getJsonView () { | |
25 | + ObjectMapper objectMapper = getObjectMapper(); | |
26 | + MappingJackson2JsonView jsonView = new MappingJackson2JsonView(objectMapper); | |
27 | + jsonView.setExtractValueFromSingleKeyModel(true); | |
28 | + return jsonView; | |
29 | + } | |
30 | + | |
31 | + @Bean(name = "objectMapper") | |
32 | + public ObjectMapper getObjectMapper() { | |
33 | + ObjectMapper mapper = new ObjectMapper(); | |
34 | + | |
35 | + mapper.registerModule(new JavaTimeModule()); | |
36 | + //기본 날짜 포맷 비활성화 | |
37 | + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); | |
38 | + | |
39 | + //새로운 날짜 포맷 세팅 | |
40 | + /*SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |
41 | + mapper.setDateFormat(dateFormat); | |
42 | + mapper.setTimeZone(TimeZone.getTimeZone("Asia/Seoul"));*/ | |
43 | + | |
44 | + return mapper; | |
45 | + } | |
46 | + | |
47 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/code/dao/CmmnCodeDAO.java
... | ... | @@ -0,0 +1,27 @@ |
1 | +package com.takensoft.taken_bi_manager.common.code.dao; | |
2 | + | |
3 | +import java.util.List; | |
4 | + | |
5 | +import org.apache.ibatis.annotations.Mapper; | |
6 | + | |
7 | +import com.takensoft.taken_bi_manager.common.code.vo.CmmnCode; | |
8 | +import com.takensoft.taken_bi_manager.user.member.vo.Member; | |
9 | + | |
10 | +/** | |
11 | + * @author 김성원 | |
12 | + * @since 2021.01.18 | |
13 | + * | |
14 | + * 공통코드 처리 관련 DAO 클래스 | |
15 | + */ | |
16 | +@Mapper | |
17 | +public interface CmmnCodeDAO { | |
18 | + | |
19 | + /** | |
20 | + * @author 김성원 | |
21 | + * @since 2021.01.10 | |
22 | + * | |
23 | + * 그룹아이디밑 코드 리스트 가져오기 | |
24 | + */ | |
25 | + public List<CmmnCode> getCodeListByGroupId(String groupId) throws Exception; | |
26 | + | |
27 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/code/service/CmmnCodeService.java
... | ... | @@ -0,0 +1,16 @@ |
1 | +package com.takensoft.taken_bi_manager.common.code.service; | |
2 | + | |
3 | +import java.util.List; | |
4 | + | |
5 | +import com.takensoft.taken_bi_manager.common.code.vo.CmmnCode; | |
6 | + | |
7 | +public interface CmmnCodeService { | |
8 | + | |
9 | + /** | |
10 | + * @author 김성원 | |
11 | + * @since 2024.01.19 | |
12 | + * | |
13 | + * 공통코드 리스트 가져오기 | |
14 | + */ | |
15 | + public List<CmmnCode> getCodeListByGroupId(String groupId) throws Exception; | |
16 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/code/service/impl/CmmnCodeServiceImpl.java
... | ... | @@ -0,0 +1,24 @@ |
1 | +package com.takensoft.taken_bi_manager.common.code.service.impl; | |
2 | + | |
3 | +import java.util.List; | |
4 | + | |
5 | +import org.springframework.beans.factory.annotation.Autowired; | |
6 | +import org.springframework.stereotype.Service; | |
7 | + | |
8 | +import com.takensoft.taken_bi_manager.common.code.dao.CmmnCodeDAO; | |
9 | +import com.takensoft.taken_bi_manager.common.code.service.CmmnCodeService; | |
10 | +import com.takensoft.taken_bi_manager.common.code.vo.CmmnCode; | |
11 | + | |
12 | +@Service | |
13 | +public class CmmnCodeServiceImpl implements CmmnCodeService { | |
14 | + | |
15 | + @Autowired | |
16 | + private CmmnCodeDAO cmmnCodeDAO; | |
17 | + | |
18 | + @Override | |
19 | + public List<CmmnCode> getCodeListByGroupId(String groupId) throws Exception { | |
20 | + // TODO Auto-generated method stub | |
21 | + return cmmnCodeDAO.getCodeListByGroupId(groupId); | |
22 | + } | |
23 | + | |
24 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/code/vo/CmmnCode.java
... | ... | @@ -0,0 +1,52 @@ |
1 | +package com.takensoft.taken_bi_manager.common.code.vo; | |
2 | + | |
3 | +import java.sql.Timestamp; | |
4 | + | |
5 | +import lombok.Getter; | |
6 | +import lombok.Setter; | |
7 | + | |
8 | +/** | |
9 | + * @author 김성원 | |
10 | + * @since 2023-12-28 | |
11 | + * | |
12 | + * 공통코드 객체 | |
13 | + */ | |
14 | +@Getter | |
15 | +@Setter | |
16 | +public class CmmnCode { | |
17 | + | |
18 | + | |
19 | + // 콩통코드 | |
20 | + private String cmmnCode; | |
21 | + | |
22 | + // 그룹코드 | |
23 | + private String groupCode; | |
24 | + | |
25 | + // 코드명 | |
26 | + private String codeNm; | |
27 | + | |
28 | + // 코드 설명 | |
29 | + private String codeDc; | |
30 | + | |
31 | + // 상위코드 (없으면 생략) | |
32 | + private String upperCode; | |
33 | + | |
34 | + // 코드 정렬순서 | |
35 | + private String codeOrdr; | |
36 | + | |
37 | + // 코드 사용여부 | |
38 | + private boolean useAt; | |
39 | + | |
40 | + // 생성일 | |
41 | + private Timestamp creatDt; | |
42 | + | |
43 | + // 생성자ID | |
44 | + private String creatId; | |
45 | + | |
46 | + // 수정일 | |
47 | + private Timestamp updtDt; | |
48 | + | |
49 | + // 수정자 ID | |
50 | + private String updtId; | |
51 | + | |
52 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/code/vo/CmmnGroup.java
... | ... | @@ -0,0 +1,42 @@ |
1 | +package com.takensoft.taken_bi_manager.common.code.vo; | |
2 | + | |
3 | +import java.sql.Timestamp; | |
4 | + | |
5 | +import lombok.Getter; | |
6 | +import lombok.Setter; | |
7 | + | |
8 | +/** | |
9 | + * @author 김성원 | |
10 | + * @since 2023-12-28 | |
11 | + * | |
12 | + * 공통코드 그룹 객체 | |
13 | + */ | |
14 | +@Getter | |
15 | +@Setter | |
16 | +public class CmmnGroup { | |
17 | + | |
18 | + // 공통코드 그룹 코드 | |
19 | + private String groupCode; | |
20 | + | |
21 | + // 공통코드 그룹 코드 명 | |
22 | + private String groupCodeNm; | |
23 | + | |
24 | + // 공통코드 그룹 설명 | |
25 | + private String groupCodeDc; | |
26 | + | |
27 | + // 공통코드 그룹 사용여부 | |
28 | + private boolean useAt; | |
29 | + | |
30 | + // 생성일 | |
31 | + private Timestamp creatDt; | |
32 | + | |
33 | + // 생성자ID | |
34 | + private String creatId; | |
35 | + | |
36 | + // 수정일 | |
37 | + private Timestamp updtDt; | |
38 | + | |
39 | + // 수정자 ID | |
40 | + private String updtId; | |
41 | + | |
42 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/config/FilterConfig.java
... | ... | @@ -0,0 +1,21 @@ |
1 | +package com.takensoft.taken_bi_manager.common.config; | |
2 | + | |
3 | +import org.springframework.boot.web.servlet.FilterRegistrationBean; | |
4 | +import org.springframework.context.annotation.Bean; | |
5 | +import org.springframework.context.annotation.Configuration; | |
6 | + | |
7 | +import com.takensoft.taken_bi_manager.common.config.filter.SessionCheck; | |
8 | + | |
9 | +@Configuration | |
10 | +public class FilterConfig { | |
11 | + | |
12 | + @Bean | |
13 | + public FilterRegistrationBean<SessionCheck> sessionCheck() { | |
14 | + FilterRegistrationBean<SessionCheck> registrationBean = new FilterRegistrationBean<>(); | |
15 | + registrationBean.setFilter(new SessionCheck()); | |
16 | + registrationBean.addUrlPatterns("/*"); | |
17 | + registrationBean.setOrder(1); | |
18 | + registrationBean.setName("sessionCheck"); | |
19 | + return registrationBean; | |
20 | + } | |
21 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/config/MybatisConfig.java
... | ... | @@ -0,0 +1,5 @@ |
1 | +package com.takensoft.taken_bi_manager.common.config; | |
2 | + | |
3 | +public class MybatisConfig { | |
4 | + | |
5 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/config/filter/SessionCheck.java
... | ... | @@ -0,0 +1,52 @@ |
1 | +package com.takensoft.taken_bi_manager.common.config.filter; | |
2 | + | |
3 | +import java.io.IOException; | |
4 | +import java.util.HashMap; | |
5 | + | |
6 | +import org.springframework.web.filter.GenericFilterBean; | |
7 | +import org.springframework.web.util.ContentCachingResponseWrapper; | |
8 | + | |
9 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
10 | +import com.takensoft.taken_bi_manager.common.util.AuthUtil; | |
11 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
12 | + | |
13 | +import jakarta.servlet.FilterChain; | |
14 | +import jakarta.servlet.ServletException; | |
15 | +import jakarta.servlet.ServletRequest; | |
16 | +import jakarta.servlet.ServletResponse; | |
17 | +import jakarta.servlet.http.HttpServletRequest; | |
18 | +import jakarta.servlet.http.HttpServletResponse; | |
19 | + | |
20 | +public class SessionCheck extends GenericFilterBean { | |
21 | + | |
22 | + @Override | |
23 | + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) | |
24 | + throws IOException, ServletException { | |
25 | + | |
26 | + HttpServletRequest httpServletRequest = (HttpServletRequest)request; | |
27 | + String uri =httpServletRequest.getRequestURI().toString(); | |
28 | + chain.doFilter(request, response); | |
29 | + // 로그인 세션 처리 (없으면 세션 없음 메세지 전달) | |
30 | + /* if(!uri.trim().contains("/login")) { | |
31 | + HashMap<String, Object> LoginUserInfo = (HashMap<String, Object>)httpServletRequest.getSession().getAttribute(AuthUtil.LOGIN_USER_SESSION); | |
32 | + if(LoginUserInfo == null) { | |
33 | + ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper((HttpServletResponse) response); | |
34 | + chain.doFilter(request, responseWrapper); | |
35 | + CustomeResultMap map = new CustomeResultMap(); | |
36 | + map.getCheckMessage().setError("로그인 정보가 없습니다."); | |
37 | + map.getCheckMessage().setStatus(100); | |
38 | + map.getCheckMessage().setSuccess(false); | |
39 | + | |
40 | + String newResponse = new ObjectMapper().writeValueAsString(map); | |
41 | + response.setContentType("application/json"); | |
42 | + response.setContentLength(newResponse.length()); | |
43 | + response.getOutputStream().write(newResponse.getBytes()); | |
44 | + }else { | |
45 | + | |
46 | + chain.doFilter(request, response); | |
47 | + } | |
48 | + } | |
49 | + */ | |
50 | + } | |
51 | + | |
52 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/dao/ConnectionApiDAO.java
... | ... | @@ -0,0 +1,21 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.api.dao; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ApiParam; | |
4 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi; | |
5 | +import org.apache.ibatis.annotations.Mapper; | |
6 | + | |
7 | +@Mapper | |
8 | +public interface ConnectionApiDAO { | |
9 | + | |
10 | + public void apiConnectionInfoInsert(ConnectionApi connectionApi) throws Exception; | |
11 | + | |
12 | + public void apiParameterInfoInsert(ApiParam apiParam)throws Exception; | |
13 | + | |
14 | + public int deletefilterItem(ConnectionApi connectionApi)throws Exception; | |
15 | + | |
16 | + public ConnectionApi selectConnectionApi(String connectionId)throws Exception; | |
17 | + | |
18 | + public int deleteApiConnectionInfo(String groupId)throws Exception; | |
19 | + | |
20 | + public int deleteApiParameterInfo(String groupId)throws Exception; | |
21 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/service/ConnectionApiService.java
... | ... | @@ -0,0 +1,48 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.api.service; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi; | |
4 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
5 | + | |
6 | +import java.util.*; | |
7 | + | |
8 | +public interface ConnectionApiService { | |
9 | + /** | |
10 | + * @author 박정하 | |
11 | + * @since 2024.11.27 | |
12 | + * | |
13 | + * OpenApi 호출 | |
14 | + */ | |
15 | + public HashMap<String, Object> apiRequestTest(ConnectionApi params) throws Exception; | |
16 | + | |
17 | + /** | |
18 | + * @author 이원호 | |
19 | + * @since 2021.11.03 | |
20 | + * | |
21 | + * OpenApi 호출 | |
22 | + */ | |
23 | + public DataTable apiRequest(ConnectionApi connApi ) throws Exception; | |
24 | + | |
25 | + /** | |
26 | + * @author 이원호 | |
27 | + * @since 2021.11.10 | |
28 | + * | |
29 | + * API 연계정보 등록 | |
30 | + */ | |
31 | + public void apiConnectionInfoInsert(ConnectionApi connectionApi) throws Exception; | |
32 | + | |
33 | + /** | |
34 | + * @author 이원호 | |
35 | + * @since 2021.11.10 | |
36 | + * | |
37 | + * 연계API 파라미터 정보 등록 | |
38 | + */ | |
39 | + public void apiParameterInfoInsert(ConnectionApi connectionApi) throws Exception; | |
40 | + | |
41 | + /** | |
42 | + * @author 이원호 | |
43 | + * @since 2021.11.10 | |
44 | + * | |
45 | + * 연계API 정보 가져오기 | |
46 | + */ | |
47 | + public ConnectionApi selectConnectionApi(String connectionId) throws Exception; | |
48 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/service/impl/ConnectionApiServiceImpl.java
... | ... | @@ -0,0 +1,235 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.api.service.impl; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.connection.api.dao.ConnectionApiDAO; | |
4 | +import com.takensoft.taken_bi_manager.common.connection.api.service.ConnectionApiService; | |
5 | +import com.takensoft.taken_bi_manager.common.connection.api.util.DataUtil; | |
6 | +import com.takensoft.taken_bi_manager.common.connection.api.util.SeolAPIUtil; | |
7 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ApiParam; | |
8 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi; | |
9 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DataTypeUtil; | |
10 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
11 | +import com.takensoft.taken_bi_manager.common.util.HTTPUtil; | |
12 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
13 | +import lombok.RequiredArgsConstructor; | |
14 | +import org.json.simple.JSONArray; | |
15 | +import org.json.simple.JSONObject; | |
16 | +import org.json.simple.parser.JSONParser; | |
17 | +import org.springframework.stereotype.Service; | |
18 | + | |
19 | +import java.util.*; | |
20 | + | |
21 | +@Service | |
22 | +@RequiredArgsConstructor | |
23 | +public class ConnectionApiServiceImpl implements ConnectionApiService { | |
24 | + private final ConnectionApiDAO connectionApiDAO; | |
25 | + | |
26 | + private Map<String, Object> findKeyResult = new HashMap<>(); | |
27 | + | |
28 | + @Override | |
29 | + public HashMap<String, Object> apiRequestTest(ConnectionApi connApi) throws Exception { | |
30 | + List<String> keys = new ArrayList<>(); | |
31 | + | |
32 | + if (connApi.getType() != 3) { | |
33 | + CommonUtil commonUtil = new CommonUtil(); | |
34 | + HTTPUtil httpcon = new HTTPUtil(); | |
35 | + String result = httpcon.HttpGetConnectionApi(connApi.getUrl(), connApi.getParams()); | |
36 | + connApi.setResult(result); | |
37 | + | |
38 | + if(connApi.getType() == 2) { | |
39 | + String jsonStr = commonUtil.xmlStrToJsonStr(connApi.getResult()); | |
40 | + connApi.setResult(jsonStr); | |
41 | + } | |
42 | + | |
43 | + JSONParser parser = new JSONParser(); | |
44 | + JSONObject jsonObject = null; | |
45 | + JSONArray jsonArray = null; | |
46 | + if(connApi.getResult().substring(0,1).equals("[")) { | |
47 | + jsonArray = (JSONArray) parser.parse(connApi.getResult()); | |
48 | + } else { | |
49 | + jsonObject = (JSONObject) parser.parse(connApi.getResult()); | |
50 | + } | |
51 | + | |
52 | + if(jsonObject != null) { | |
53 | + Map<String, Object> map = commonUtil.jsonObjectToMap(jsonObject); | |
54 | + | |
55 | + if (map.containsKey("response")) { | |
56 | + Map<String, Object> response = (Map<String, Object>) map.get("response"); | |
57 | + if (response.containsKey("body")) { | |
58 | + Map<String, Object> body = (Map<String, Object>) response.get("body"); | |
59 | + if (body.containsKey("item")) { | |
60 | + keys.add("response>body>item"); | |
61 | + } else if (body.containsKey("items")) { | |
62 | + if (body.get("items").toString().substring(0,1).equals("[")) { | |
63 | + keys.add("response>body>items"); | |
64 | + } else { | |
65 | + keys.add("response>body>items>item"); | |
66 | + } | |
67 | + } | |
68 | + } | |
69 | + } else { | |
70 | + String keyString = result.substring(0, result.indexOf('[')); | |
71 | + String[] keysArray = keyString.split(","); | |
72 | + String key = keysArray[keysArray.length - 1].substring(1, keysArray[keysArray.length - 1].length() - 2); | |
73 | + | |
74 | + findKeyResult = new HashMap<>(); | |
75 | + findKeyResult.put("key", null); | |
76 | + findKeyResult.put("totalRow", 0); | |
77 | + findKey(map, key); | |
78 | + | |
79 | + keys.add((String) findKeyResult.get("key")); | |
80 | + } | |
81 | + } | |
82 | + } | |
83 | + | |
84 | + HashMap<String, Object> resultMap = new HashMap<>(); | |
85 | + resultMap.put("key", keys); | |
86 | + return resultMap; | |
87 | + } | |
88 | + | |
89 | + private void findKey(Map<String, Object> map, String key) { | |
90 | + for (Map.Entry<String, Object> entrySet : map.entrySet()) { | |
91 | + if (entrySet.getKey().equals(key)) { | |
92 | + String resultKey = (String) findKeyResult.get("key"); | |
93 | + if (resultKey == null) { | |
94 | + findKeyResult.put("key", entrySet.getKey() + ">"); | |
95 | + } else { | |
96 | + findKeyResult.put("key", resultKey + entrySet.getKey() + ">"); | |
97 | + } | |
98 | + List<HashMap<String, Object>> datas = (List<HashMap<String, Object>>) entrySet.getValue(); | |
99 | + findKeyResult.put("totalRow", datas.size()); | |
100 | + } else { | |
101 | + if (entrySet.getValue() instanceof Map) { | |
102 | + Map<String, Object> newMap = (Map<String, Object>) entrySet.getValue(); | |
103 | + findKey(newMap, key); | |
104 | + } | |
105 | + } | |
106 | + } | |
107 | + } | |
108 | + | |
109 | + @Override | |
110 | + public DataTable apiRequest(ConnectionApi connApi) throws Exception { | |
111 | + List<ApiParam> paramList = connApi.getParams(); | |
112 | + List<ApiParam> realParams = new ArrayList<>(); | |
113 | + HashMap<String, Integer> pageParams = new HashMap<>(); | |
114 | + for (ApiParam param : paramList) { | |
115 | + if (param.getIndex() < 0) { | |
116 | + pageParams.put(param.getKey(), (Integer) param.getValue()); | |
117 | + } else { | |
118 | + realParams.add(param); | |
119 | + } | |
120 | + } | |
121 | + | |
122 | + DataTable dataTable = new DataTable(); | |
123 | + if (connApi.getType() != 3) { | |
124 | + CommonUtil commonUtil = new CommonUtil(); | |
125 | + HTTPUtil httpcon = new HTTPUtil(); | |
126 | + connApi.setResult(httpcon.HttpGetConnectionApi(connApi.getUrl(), realParams)); | |
127 | + | |
128 | + if(connApi.getType() == 2) { | |
129 | + String jsonStr = commonUtil.xmlStrToJsonStr(connApi.getResult()); | |
130 | + connApi.setResult(jsonStr); | |
131 | + } | |
132 | + | |
133 | + JSONParser parser = new JSONParser(); | |
134 | + JSONObject jsonObject = null; | |
135 | + JSONArray jsonArray = null; | |
136 | + if(connApi.getResult().substring(0,1).equals("[")) { | |
137 | + jsonArray = (JSONArray) parser.parse(connApi.getResult()); | |
138 | + } else { | |
139 | + jsonObject = (JSONObject) parser.parse(connApi.getResult()); | |
140 | + } | |
141 | + | |
142 | + List<Map<String,Object>> dataList = new ArrayList<>(); | |
143 | + | |
144 | + // depth 리스트 | |
145 | + if(jsonArray == null) { | |
146 | + // jsonObject to Map | |
147 | + Map<String, Object> resultMap = commonUtil.jsonObjectToMap(jsonObject); | |
148 | + String [] depthList = connApi.getDepth().split(">"); | |
149 | + | |
150 | + int deptCount = 0; | |
151 | + for(String depth : depthList) { | |
152 | + deptCount++; | |
153 | + depth = depth.trim(); | |
154 | + Object temp = (Object)resultMap.get(depth); | |
155 | + // 리스트 판별 | |
156 | + if(temp instanceof List) { | |
157 | + if (deptCount < depthList.length) { | |
158 | + List<Map<String, Object>> tempList = (List<Map<String, Object>>) temp; | |
159 | + resultMap = tempList.get(0); | |
160 | + } else { | |
161 | + dataList = (List<Map<String, Object>>) temp; | |
162 | + } | |
163 | + }else { | |
164 | + resultMap = (Map<String, Object>) temp; | |
165 | + } | |
166 | + } | |
167 | + }else { | |
168 | + dataList = (List<Map<String, Object>>)jsonArray; | |
169 | + } | |
170 | + | |
171 | + int max = 0; | |
172 | + int indx = 0; | |
173 | + | |
174 | + // 최대 길이의 키값을 가진 객체 구하기 | |
175 | + for(int i = 0 ; i < dataList.size() ; i++){ | |
176 | + if(dataList.get(i).keySet().size() > max) { | |
177 | + max = dataList.get(i).keySet().size(); | |
178 | + indx = i; | |
179 | + } | |
180 | + } | |
181 | + // 빈정보 공백으로 채우기 | |
182 | + for(Map<String, Object> item : dataList ) { | |
183 | + if(max != item.size()) { | |
184 | + for (Map.Entry<String, Object> entry : dataList.get(indx).entrySet()) | |
185 | + { | |
186 | + if(item.get(entry.getKey()) == null) { | |
187 | + item.put(entry.getKey(),""); | |
188 | + } | |
189 | + } | |
190 | + } | |
191 | + } | |
192 | + | |
193 | + dataTable = DataUtil.setMaptoDataTable(dataList); | |
194 | + DataUtil.setColumnMetaData(dataTable, false); | |
195 | + DataTypeUtil.convertDataTableColumMeta(dataTable); | |
196 | + } else { | |
197 | + SeolAPIUtil seolAPIUtil = new SeolAPIUtil(); | |
198 | + dataTable = seolAPIUtil.getSeolMain("http://111.8.5.63:3100/stmr/websvc/std/ws?wsdl=SOWNN00213", "5110000SOI001"); | |
199 | + } | |
200 | + | |
201 | + List<List<Object>> rowData = dataTable.getRowData(); | |
202 | + Integer onePageRow = pageParams.get("onePageRow"); | |
203 | + Integer currentPage = pageParams.get("currentPage"); | |
204 | + if (onePageRow != null && onePageRow != 0) { | |
205 | + int start = currentPage == 1 ? 0 : onePageRow * (currentPage - 1); | |
206 | + int end = start + onePageRow; | |
207 | + | |
208 | + List<List<Object>> newRowData = new ArrayList<>(); | |
209 | + for (int i = start; i < end; i++) { | |
210 | + newRowData.add(rowData.get(i)); | |
211 | + } | |
212 | + dataTable.setRowData(newRowData); | |
213 | + } | |
214 | + | |
215 | + return dataTable; | |
216 | + } | |
217 | + | |
218 | + @Override | |
219 | + public void apiConnectionInfoInsert(ConnectionApi connectionApi) throws Exception { | |
220 | + connectionApiDAO.apiConnectionInfoInsert(connectionApi); | |
221 | + } | |
222 | + | |
223 | + @Override | |
224 | + public void apiParameterInfoInsert(ConnectionApi connectionApi) throws Exception { | |
225 | + for(int i=0; i<connectionApi.getParams().size(); i++) { | |
226 | + connectionApi.getParams().get(i).setParamId(connectionApi.getConnectionId()); | |
227 | + connectionApiDAO.apiParameterInfoInsert(connectionApi.getParams().get(i)); | |
228 | + } | |
229 | + } | |
230 | + | |
231 | + @Override | |
232 | + public ConnectionApi selectConnectionApi(String connectionId) throws Exception { | |
233 | + return connectionApiDAO.selectConnectionApi(connectionId); | |
234 | + } | |
235 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/util/ApiUtil.java
... | ... | @@ -0,0 +1,132 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.api.util; | |
2 | + | |
3 | +import java.util.ArrayList; | |
4 | +import java.util.HashMap; | |
5 | +import java.util.List; | |
6 | +import java.util.Map; | |
7 | + | |
8 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
9 | +import org.json.simple.JSONArray; | |
10 | +import org.json.simple.JSONObject; | |
11 | +import org.json.simple.parser.JSONParser; | |
12 | + | |
13 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
14 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi; | |
15 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
16 | +import com.takensoft.taken_bi_manager.common.util.HTTPUtil; | |
17 | + | |
18 | +/** | |
19 | + * @author 김성원 | |
20 | + * @since 2024.01.12 | |
21 | + * | |
22 | + * API 연계 관련 기능 리스트 입니다. | |
23 | + */ | |
24 | +public class ApiUtil { | |
25 | + /** | |
26 | + * @author 김성원 | |
27 | + * @since 2024.01.12 | |
28 | + * | |
29 | + * OpenApi 데이터 수집 기능 | |
30 | + */ | |
31 | + public static ConnectionApi apiRequest(ConnectionApi connApi) throws Exception { | |
32 | + ObjectMapper mapper = new ObjectMapper(); | |
33 | + | |
34 | + // 새올데이터 API 데이터 수집 | |
35 | + if (connApi.getType() == 3) { | |
36 | + SeolAPIUtil seolAPIUtil = new SeolAPIUtil(); | |
37 | + DataTable dataTable = seolAPIUtil.getSeolMain("http://111.8.5.63:3100/stmr/websvc/std/ws?wsdl=SOWNN00213", "5110000SOI001"); | |
38 | + connApi.setResult(dataTable.toString()); | |
39 | + } else { | |
40 | + HTTPUtil httpcon = new HTTPUtil(); | |
41 | + connApi.setResult(httpcon.HttpGetConnectionApi(connApi.getUrl(), connApi.getParams())); | |
42 | + } | |
43 | + | |
44 | + return connApi; | |
45 | + } | |
46 | + | |
47 | + /** | |
48 | + * @author 김성원 | |
49 | + * @since 2024.01.12 | |
50 | + * | |
51 | + * OpenApi 데이터 수집 기능 | |
52 | + */ | |
53 | + public static List<Map<String,Object>> getApiDataList (ConnectionApi connApi) throws Exception{ | |
54 | + ObjectMapper mapper = new ObjectMapper(); | |
55 | + | |
56 | + // depth 리스트 | |
57 | + String [] depthList = connApi.getDepth().split(">"); | |
58 | + CommonUtil commonUtil = new CommonUtil(); | |
59 | + | |
60 | + // Return Type : 1=JSON, 2=XML | |
61 | + if(connApi.getType() ==2) { | |
62 | + // XML String to JSON String | |
63 | + String jsonStr = commonUtil.xmlStrToJsonStr(connApi.getResult()); | |
64 | + connApi.setResult(jsonStr); | |
65 | + } | |
66 | + | |
67 | + JSONParser parser = new JSONParser(); | |
68 | + | |
69 | + JSONObject jsonObject = null; | |
70 | + JSONArray jsonArray = null; | |
71 | + | |
72 | + if(connApi.getResult().substring(0,1).equals("[")) { | |
73 | + jsonArray = (JSONArray) parser.parse(connApi.getResult()); | |
74 | + }else { | |
75 | + jsonObject = (JSONObject) parser.parse(connApi.getResult()); | |
76 | + } | |
77 | + | |
78 | + List<Map<String, Object>> apiDataList = new ArrayList<Map<String, Object>>(); | |
79 | + | |
80 | + if(jsonArray == null) { | |
81 | + // jsonObject to Map | |
82 | + Map<String, Object> resultMap = new HashMap<String, Object>(); | |
83 | + resultMap = commonUtil.jsonObjectToMap(jsonObject); | |
84 | + | |
85 | + int deptCount = 0; | |
86 | + for(String depth : depthList) { | |
87 | + deptCount++; | |
88 | + depth = depth.trim(); | |
89 | + Object temp = (Object)resultMap.get(depth); | |
90 | + | |
91 | + // 리스트 판별 | |
92 | + if(temp instanceof List) { | |
93 | + if(deptCount < depthList.length) { | |
94 | + List<Map<String, Object>> tempList = (List<Map<String, Object>>) temp; | |
95 | + resultMap = tempList.get(0); | |
96 | + }else { | |
97 | + apiDataList = (List<Map<String, Object>>) temp; | |
98 | + } | |
99 | + }else { | |
100 | + resultMap = (Map<String, Object>) temp; | |
101 | + } | |
102 | + } | |
103 | + }else { | |
104 | + apiDataList = (List<Map<String, Object>>)jsonArray; | |
105 | + } | |
106 | + | |
107 | + int max = 0; | |
108 | + int indx = 0; | |
109 | + | |
110 | + // 최대 길이의 키값을 가진 객체 구하기 | |
111 | + for(int i = 0 ; i < apiDataList.size() ; i++){ | |
112 | + if(apiDataList.get(i).keySet().size() > max) { | |
113 | + max = apiDataList.get(i).keySet().size(); | |
114 | + indx = i; | |
115 | + } | |
116 | + } | |
117 | + | |
118 | + // 빈정보 공백으로 채우기 | |
119 | + for(Map<String, Object> item : apiDataList ) { | |
120 | + if(max != item.size()) { | |
121 | + for (Map.Entry<String, Object> entry : apiDataList.get(indx).entrySet()) | |
122 | + { | |
123 | + if(item.get(entry.getKey()) == null) { | |
124 | + item.put(entry.getKey(),""); | |
125 | + } | |
126 | + } | |
127 | + } | |
128 | + } | |
129 | + | |
130 | + return apiDataList; | |
131 | + } | |
132 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/util/DataUtil.java
... | ... | @@ -0,0 +1,1145 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.api.util; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.DataType; | |
4 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
5 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
6 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
7 | +import com.takensoft.taken_bi_manager.data.vo.ColumnValue; | |
8 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
9 | +import com.takensoft.taken_bi_manager.data.vo.DatasetPost; | |
10 | + | |
11 | +import java.util.*; | |
12 | +import java.util.stream.Collectors; | |
13 | + | |
14 | +/** | |
15 | + * @author 최정우 | |
16 | + * @since 2019.11.19 | |
17 | + * | |
18 | + * Dataset과 관련된 Util입니다. | |
19 | + */ | |
20 | +public class DataUtil { | |
21 | + | |
22 | + | |
23 | + public final static String COLUMN_NAME = "col"; | |
24 | + | |
25 | + | |
26 | + /** | |
27 | + * @author 최정우 | |
28 | + * @since 2019.11.19 | |
29 | + * | |
30 | + * DataTable의 ColumnDatas와 rowData를 활용하여 '컬럼의 메타 정보 세팅' | |
31 | + */ | |
32 | + public static void setColumnMetaData (DataTable dataTable, boolean addData) throws Exception { | |
33 | + | |
34 | + | |
35 | + //데이터가 없을 때 return | |
36 | + if (dataTable.getColumnDatas() == null || dataTable.getColumnDatas().size() == 0) { | |
37 | + dataTable.getCheckMessage().setSuccess(false); | |
38 | + dataTable.getCheckMessage().setMessage("컬럼 정보가 없습니다."); | |
39 | + return; | |
40 | + } else { | |
41 | + | |
42 | + //한 행의 총 varchar size | |
43 | + int varcharTotalSize = 0; | |
44 | + | |
45 | + | |
46 | + // 맥스 사이즈 정하겠음 | |
47 | + //컬럼 정보 세팅 (시작) | |
48 | + for(int cellIndex = 0; cellIndex < dataTable.getColumnDatas().size(); cellIndex++) { | |
49 | + | |
50 | + int maxLength = 10; | |
51 | + //원본 컬럼명 | |
52 | + String originColumnName = dataTable.getColumnDatas().get(cellIndex).getColumnNm(); | |
53 | + | |
54 | + //DB에 생성될 컬럼명 set | |
55 | + if (StringUtil.isEmpty(dataTable.getColumnDatas().get(cellIndex).getColumnNm()) == true) { | |
56 | + dataTable.getColumnDatas().get(cellIndex).setColumnNm(COLUMN_NAME + cellIndex); | |
57 | + } | |
58 | + | |
59 | + //컬럼 Index set | |
60 | + dataTable.getColumnDatas().get(cellIndex).setOrdr(cellIndex); | |
61 | + | |
62 | + | |
63 | + dataTable.getColumnDatas().get(cellIndex).setDisplyColumnNm(originColumnName); | |
64 | + | |
65 | + | |
66 | + | |
67 | + | |
68 | + //열(컬럼)의 데이터 타입 (컬럼의 열 데이터가 없을 때, STRING 타입) | |
69 | + DataType dataType = dataTable.getColumnDatas().get(cellIndex).getDataTy(); | |
70 | + | |
71 | + //컬럼별 데이터의 데이터 타입 목록 (중복 등록은 방지하기 위해 Set으로 설정) | |
72 | + Set<DataType> datatypes = new HashSet<DataType>(); | |
73 | + | |
74 | + | |
75 | + //각 컬럼 목록 > 컬럼별 데이터 목록 세팅 | |
76 | + | |
77 | + List<ColumnValue> columnValues = new ArrayList<ColumnValue>(); | |
78 | + for(int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) { | |
79 | + | |
80 | + //cellIndex열 중 rowIndex행 값-value | |
81 | + String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString(); | |
82 | + | |
83 | + if(!StringUtil.isEmpty(value) && value.length() > maxLength) { | |
84 | + maxLength = value.length(); | |
85 | + } | |
86 | + | |
87 | + /* | |
88 | + * 문자열이 비어있거나 | |
89 | + * 문자열이 Null or null or NULL인 경우 실제 null값 세팅 | |
90 | + * */ | |
91 | + if (StringUtil.isEmpty(value) || StringUtil.isNullText(value) == true) { | |
92 | + dataTable.getRowData().get(rowIndex).set(cellIndex, null); | |
93 | + value = null; | |
94 | + } | |
95 | + | |
96 | + //해당 '값'의 '데이터 타입 조회' | |
97 | + DataType type = DataType.getDataType(value); | |
98 | + | |
99 | + //Cell 데이터 값 및 타입 세팅 | |
100 | + | |
101 | + if(addData == true) { | |
102 | + ColumnValue columnValue = new ColumnValue(); | |
103 | + columnValue.setValue(value);//Cell에 조회된 '데이터 값' 세팅 | |
104 | + columnValue.setDataType(type);//Cell에 조회된 '데이터 타입' 세팅 //dataTable에 Cell 데이터 값 및 타입 세팅 | |
105 | + columnValues.add(columnValue); | |
106 | + } | |
107 | + | |
108 | + | |
109 | + //컬럼별 데이터의 데이터 타입 목록에 데이터 타입 입력 | |
110 | + datatypes.add(type); | |
111 | + | |
112 | + if(rowIndex > 100000) { | |
113 | + | |
114 | + if(dataTable.getRowData().size() > 10000 && rowIndex < dataTable.getRowData().size() - 10000 ) { | |
115 | + rowIndex = dataTable.getRowData().size() - 10000; | |
116 | + } | |
117 | + // break; | |
118 | + } | |
119 | + } | |
120 | + //각 컬럼 목록 > 컬럼별 데이터 목록 세팅 | |
121 | + dataTable.getColumnDatas().get(cellIndex).setColumnValues(columnValues); | |
122 | + | |
123 | + //해당 열(컬럼)의 데이터 타입이 지정되지 않았을 때 -> #읽은 컬럼 데이터를 바탕으로 데이터 타입지정# | |
124 | + if (dataType == null) { | |
125 | + dataType = getColumnDataType(datatypes); | |
126 | + dataTable.getColumnDatas().get(cellIndex).setDataType(dataType); | |
127 | + } | |
128 | + | |
129 | + | |
130 | + | |
131 | + /*DB데이터 타입 생성*/ | |
132 | + if (dataType == DataType.STRING) {//문자열일 때 => 최대 길이 값 구하기 | |
133 | + ColumnValue columnValue = null; | |
134 | + | |
135 | + //해당 열의 문자열 크기 | |
136 | + int size = maxLength; | |
137 | + | |
138 | + //컬럼의 열 데이터가 존재할 때, 가장 긴 문자열의 글자수 구하기 | |
139 | + /* | |
140 | + * if (columnValues.size() > 0) { //null값 제외한 목록 만들기 List<ColumnValue> | |
141 | + * noneNullColumnValues = columnValues.stream().filter(s -> s.getValue() != | |
142 | + * null).collect(Collectors.toList()); | |
143 | + * | |
144 | + * if (noneNullColumnValues != null && noneNullColumnValues.size() > 0) { //최대 | |
145 | + * 길이 값 구하기 columnValue = noneNullColumnValues.stream().max((s1, s2) -> | |
146 | + * StringUtil.stringLength(s1.getValue()) - | |
147 | + * StringUtil.stringLength(s2.getValue())).get(); //가장 긴 문자열의 글자수 size = | |
148 | + * StringUtil.stringLength(columnValue.getValue()); } } | |
149 | + */ | |
150 | + | |
151 | + //테이블 생성시에 필요한 DB데이터 타입으로 Convert | |
152 | + String dbDataType = DataType.convertDbDataType(dataType, size); | |
153 | + | |
154 | + //DB데이터 타입 입력 | |
155 | + dataTable.getColumnDatas().get(cellIndex).setDbDataType(dbDataType); | |
156 | + //DB데이터 타입이 varchar일 때 => 데이터 타입 크기 입력 | |
157 | + if (dbDataType.equals("varchar")) { | |
158 | + | |
159 | + dataTable.getColumnDatas().get(cellIndex).setDataSize(size);//데이터 타입 크기 입력 | |
160 | + | |
161 | + //varchar 총 사이즈에 추가 | |
162 | + varcharTotalSize += size; | |
163 | + } | |
164 | + } else if (dataTable.getColumnDatas().get(cellIndex).getDataTy() == DataType.DATE) { | |
165 | + | |
166 | + //text -> date형식으로 변경 | |
167 | + for(int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) { | |
168 | + //cellIndex열 중 rowIndex행 값-value | |
169 | + String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString(); | |
170 | + String dateTextValue = CommonUtil.parseDateText(value); | |
171 | + dataTable.getRowData().get(rowIndex).set(cellIndex, dateTextValue); | |
172 | + } | |
173 | + | |
174 | + dataTable.getColumnDatas().get(cellIndex).setDbDataType(DataType.convertDbDataType(dataType, null)); | |
175 | + dataTable.getColumnDatas().get(cellIndex).setDataSize(20); | |
176 | + | |
177 | + } else {//'문자열'도 아니고 '날짜'도아닐 때 => DB데이터 타입 입력 | |
178 | + dataTable.getColumnDatas().get(cellIndex).setDbDataType(DataType.convertDbDataType(dataType, null)); | |
179 | + dataTable.getColumnDatas().get(cellIndex).setDataSize(20); | |
180 | + } | |
181 | + | |
182 | + }//cell for문 끝 | |
183 | + | |
184 | + dataTable.getCheckMessage().setSuccess(true); | |
185 | + dataTable.getCheckMessage().setMessage("컬럼 메타 정보 세팅 완료"); | |
186 | + } | |
187 | + } | |
188 | + | |
189 | + | |
190 | + /** | |
191 | + * @author 최정우 | |
192 | + * @since 2019.11.19 | |
193 | + * | |
194 | + * DataTable의 ColumnDatas와 rowData를 활용하여 '컬럼의 메타 정보 세팅' 실제 컬럼데이터 적재 없음 | |
195 | + */ | |
196 | + public static void setColumnMetaDataRihjt (DataTable dataTable) throws Exception { | |
197 | + | |
198 | + } | |
199 | + | |
200 | + | |
201 | + /** | |
202 | + * @author 최정우 | |
203 | + * @since 2019.11.19 | |
204 | + * | |
205 | + * rowData를 columnData로 Convert | |
206 | + */ | |
207 | + public static List<ColumnData> columnDataCreateByFile (List<List<Object>> rowData) throws Exception { | |
208 | + //각 컬럼 목록 | |
209 | + List<ColumnData> columnDatas = new ArrayList<ColumnData>(); | |
210 | + //데이터가 없을 때 return | |
211 | + if (rowData == null || rowData.size() == 0) return columnDatas; | |
212 | + | |
213 | + //최대 Cell 크기 | |
214 | + int cellMaxSize = rowDataCellMaxSize(rowData); | |
215 | + | |
216 | + //rowData cell의 빈공간 채우기 | |
217 | + //rowData = rowDataCellInfill(rowData, cellMaxSize); | |
218 | + rowDataCellInfill(rowData, cellMaxSize); | |
219 | + | |
220 | + | |
221 | + //한 핸의 총 varchar size | |
222 | + int varcharTotalSize = 0; | |
223 | + | |
224 | + //컬럼 정보 세팅 (시작) | |
225 | + for(int cellIndex = 0; cellIndex < cellMaxSize; cellIndex++) { | |
226 | + //해더 정보 세팅 | |
227 | + ColumnData columnData = new ColumnData(); | |
228 | + String originColumnName = rowData.get(0).get(cellIndex).toString(); | |
229 | + columnData.setOrginlColumnNm(originColumnName); | |
230 | + columnData.setColumnNm(COLUMN_NAME + cellIndex); | |
231 | + columnData.setOrdr(cellIndex); | |
232 | + if (StringUtil.isEmpty(originColumnName) == true) { | |
233 | + columnData.setDisplyColumnNm(COLUMN_NAME + cellIndex); | |
234 | + } else { | |
235 | + columnData.setDisplyColumnNm(originColumnName); | |
236 | + } | |
237 | + //해더 정보 세팅 | |
238 | + | |
239 | + //컬럼별 데이터의 데이터 타입 목록 (중복 등록은 방지하기 위해 Set으로 설정) | |
240 | + Set<DataType> datatypes = new HashSet<DataType>(); | |
241 | + | |
242 | + //각 컬럼 목록 > 컬럼별 데이터 목록 세팅 | |
243 | + List<ColumnValue> columnValues = new ArrayList<ColumnValue>(); | |
244 | + for(int rowIndex = 1; rowIndex < rowData.size(); rowIndex++) { | |
245 | + String value = rowData.get(rowIndex).get(cellIndex).toString(); | |
246 | + DataType type = DataType.getDataType(value); | |
247 | + | |
248 | + //Cell 데이터 값 및 타입 세팅 | |
249 | + ColumnValue columnValue = new ColumnValue(); | |
250 | + columnValue.setValue(value);//Cell에 조회된 '데이터 값' 세팅 | |
251 | + columnValue.setDataType(type);//Cell에 조회된 '데이터 타입' 세팅 | |
252 | + //dataTable에 Cell 데이터 값 및 타입 세팅 | |
253 | + columnValues.add(columnValue); | |
254 | + | |
255 | + //컬럼별 데이터의 데이터 타입 목록에 데이터 타입 입력 | |
256 | + datatypes.add(type); | |
257 | + } | |
258 | + //각 컬럼 목록 > 컬럼별 데이터 목록 세팅 | |
259 | + columnData.setColumnValues(columnValues); | |
260 | + | |
261 | + //컬럼의 데이터 타입 지정 (컬럼의 열 데이터가 없을 때, STRING 타입) | |
262 | + DataType dataType = getColumnDataType(datatypes); | |
263 | + columnData.setDataType(dataType); | |
264 | + | |
265 | + //DB데이터 타입 생성 | |
266 | + if (dataType == DataType.STRING) {//문자열일 때 => 최대 길이 값 구하기 | |
267 | + ColumnValue columnValue = null; | |
268 | + int size = 50; | |
269 | + //컬럼의 열 데이터가 존재할 때 | |
270 | + if (columnValues.size() > 0) { | |
271 | + //최대 길이 값 구하기 | |
272 | + columnValue = columnValues.stream().filter(s -> Objects.nonNull(s.getValue())).max((s1, s2) -> StringUtil.stringLength(s1.getValue()) - StringUtil.stringLength(s2.getValue())).get(); | |
273 | + //가장 긴 문자열의 글자수 | |
274 | + size = StringUtil.stringLength(columnValue.getValue()); | |
275 | + } | |
276 | + | |
277 | + //테이블 생성시에 필요한 DB데이터 타입으로 Convert | |
278 | + String dbDataType = DataType.convertDbDataType(dataType, size); | |
279 | + | |
280 | + //DB데이터 타입 입력 | |
281 | + columnData.setDbDataType(dbDataType); | |
282 | + //DB데이터 타입이 varchar일 때 => 데이터 타입 크기 입력 | |
283 | + if (dbDataType.equals("varchar")) { | |
284 | +// if (size < SystemCode.DEFAULT_VARCHAR_SIZE) { | |
285 | +// size = SystemCode.DEFAULT_VARCHAR_SIZE; | |
286 | +// } | |
287 | + columnData.setDataSize(size);//데이터 타입 크기 입력 | |
288 | + | |
289 | + //varchar 총 사이즈에 추가 | |
290 | + varcharTotalSize += size; | |
291 | + } | |
292 | + } else {//문자열이 아닐 때 => DB데이터 타입 입력 | |
293 | + columnData.setDbDataType(DataType.convertDbDataType(dataType, null)); | |
294 | + } | |
295 | + | |
296 | + //컬럼 목록에 컬럼 정보 추가 | |
297 | + columnDatas.add(columnData); | |
298 | + } | |
299 | + | |
300 | + | |
301 | +// if (varcharTotalSize) | |
302 | +// for(int i = 0; i < columnDatas.size(); i++) { | |
303 | +// columnDatas.get(i). | |
304 | +// } | |
305 | + | |
306 | + return columnDatas; | |
307 | + } | |
308 | + | |
309 | + /** | |
310 | + * @author 최정우 | |
311 | + * @since 2019.11.19 | |
312 | + * | |
313 | + * rowData를 columnData로 Convert | |
314 | + */ | |
315 | + public static List<ColumnData> columnDataCreateByAPI (List<List<Object>> rowData, List<Map<String, String>> columns) throws Exception { | |
316 | + //각 컬럼 목록 | |
317 | + List<ColumnData> columnDatas = new ArrayList<ColumnData>(); | |
318 | + //데이터가 없을 때 return | |
319 | + if (rowData == null || rowData.size() == 0 || columns == null || columns.size() == 0) return columnDatas; | |
320 | + | |
321 | + //최대 Cell 크기 | |
322 | + int cellMaxSize = rowDataCellMaxSize(rowData); | |
323 | + | |
324 | + //rowData cell의 빈공간 채우기 | |
325 | + //rowData = rowDataCellInfill(rowData, cellMaxSize); | |
326 | + rowDataCellInfill(rowData, cellMaxSize); | |
327 | + | |
328 | + //한 핸의 총 varchar size | |
329 | + int varcharTotalSize = 0; | |
330 | + | |
331 | + //컬럼 정보 세팅 (시작) | |
332 | + for(int cellIndex = 0; cellIndex < cellMaxSize; cellIndex++) { | |
333 | + //해더 정보 세팅 | |
334 | + ColumnData columnData = new ColumnData(); | |
335 | + String originColumnName = rowData.get(0).get(cellIndex).toString(); | |
336 | + columnData.setOrginlColumnNm(originColumnName); | |
337 | + columnData.setColumnNm(COLUMN_NAME + cellIndex); | |
338 | + columnData.setOrdr(cellIndex); | |
339 | + if (StringUtil.isEmpty(originColumnName) == true) { | |
340 | + columnData.setDisplyColumnNm(COLUMN_NAME + cellIndex); | |
341 | + } else { | |
342 | + columnData.setDisplyColumnNm(originColumnName); | |
343 | + } | |
344 | + //해더 정보 세팅 | |
345 | + | |
346 | + //컬럼별 데이터의 데이터 타입 목록 (중복 등록은 방지하기 위해 Set으로 설정) | |
347 | + Set<DataType> datatypes = new HashSet<DataType>(); | |
348 | + | |
349 | + //각 컬럼 목록 > 컬럼별 데이터 목록 세팅 | |
350 | + List<ColumnValue> columnValues = new ArrayList<ColumnValue>(); | |
351 | + for(int rowIndex = 1; rowIndex < rowData.size(); rowIndex++) { | |
352 | + String value = rowData.get(rowIndex).get(cellIndex).toString(); | |
353 | + DataType type = DataType.getDataType(value); | |
354 | + | |
355 | + //Cell 데이터 값 및 타입 세팅 | |
356 | + ColumnValue columnValue = new ColumnValue(); | |
357 | + columnValue.setValue(value);//Cell에 조회된 '데이터 값' 세팅 | |
358 | + columnValue.setDataType(type);//Cell에 조회된 '데이터 타입' 세팅 | |
359 | + //dataTable에 Cell 데이터 값 및 타입 세팅 | |
360 | + columnValues.add(columnValue); | |
361 | + | |
362 | + //컬럼별 데이터의 데이터 타입 목록에 데이터 타입 입력 | |
363 | + datatypes.add(type); | |
364 | + } | |
365 | + //각 컬럼 목록 > 컬럼별 데이터 목록 세팅 | |
366 | + columnData.setColumnValues(columnValues); | |
367 | + | |
368 | + //컬럼의 데이터 타입 지정 (컬럼의 열 데이터가 없을 때, STRING 타입) | |
369 | + DataType dataType = getColumnDataType(datatypes); | |
370 | + columnData.setDataType(dataType); | |
371 | + | |
372 | + //DB데이터 타입 생성 | |
373 | + if (dataType == DataType.STRING) {//문자열일 때 => 최대 길이 값 구하기 | |
374 | + ColumnValue columnValue = null; | |
375 | + int size = 50; | |
376 | + //컬럼의 열 데이터가 존재할 때 | |
377 | + if (columnValues.size() > 0) { | |
378 | + //최대 길이 값 구하기 | |
379 | + columnValue = columnValues.stream().filter(s -> Objects.nonNull(s.getValue())).max((s1, s2) -> StringUtil.stringLength(s1.getValue()) - StringUtil.stringLength(s2.getValue())).get(); | |
380 | + //가장 긴 문자열의 글자수 | |
381 | + size = StringUtil.stringLength(columnValue.getValue()); | |
382 | + } | |
383 | + | |
384 | + //테이블 생성시에 필요한 DB데이터 타입으로 Convert | |
385 | + String dbDataType = DataType.convertDbDataType(dataType, size); | |
386 | + | |
387 | + //DB데이터 타입 입력 | |
388 | + columnData.setDbDataType(dbDataType); | |
389 | + //DB데이터 타입이 varchar일 때 => 데이터 타입 크기 입력 | |
390 | + if (dbDataType.equals("varchar")) { | |
391 | +// if (size < SystemCode.DEFAULT_VARCHAR_SIZE) { | |
392 | +// size = SystemCode.DEFAULT_VARCHAR_SIZE; | |
393 | +// } | |
394 | + columnData.setDataSize(size);//데이터 타입 크기 입력 | |
395 | + | |
396 | + //varchar 총 사이즈에 추가 | |
397 | + varcharTotalSize += size; | |
398 | + } | |
399 | + } else {//문자열이 아닐 때 => DB데이터 타입 입력 | |
400 | + columnData.setDbDataType(DataType.convertDbDataType(dataType, null)); | |
401 | + } | |
402 | + | |
403 | + //컬럼 목록에 컬럼 정보 추가 | |
404 | + columnDatas.add(columnData); | |
405 | + } | |
406 | + | |
407 | + | |
408 | +// if (varcharTotalSize) | |
409 | +// for(int i = 0; i < columnDatas.size(); i++) { | |
410 | +// columnDatas.get(i). | |
411 | +// } | |
412 | + | |
413 | + return columnDatas; | |
414 | + } | |
415 | + | |
416 | + public static List<ColumnData> columnDataCreateByCrawling(List<List<Object>> rowData) throws Exception { | |
417 | + //각 컬럼 목록 | |
418 | + List<ColumnData> columnDatas = new ArrayList<ColumnData>(); | |
419 | + //데이터가 없을 때 return | |
420 | + if (rowData == null || rowData.size() == 0) return columnDatas; | |
421 | + | |
422 | + //최대 Cell 크기 | |
423 | + int cellMaxSize = rowDataCellMaxSize(rowData); | |
424 | + | |
425 | + //rowData cell의 빈공간 채우기 | |
426 | + //rowData = rowDataCellInfill(rowData, cellMaxSize); | |
427 | + rowDataCellInfill(rowData, cellMaxSize); | |
428 | + | |
429 | + //컬럼 정보 세팅 (시작) | |
430 | + for(int cellIndex = 0; cellIndex < cellMaxSize; cellIndex++) { | |
431 | + //해더 정보 세팅 | |
432 | + ColumnData columnData = new ColumnData(); | |
433 | + String originColumnName = rowData.get(0).get(cellIndex).toString(); | |
434 | + columnData.setOrginlColumnNm(originColumnName); | |
435 | + columnData.setColumnNm(originColumnName); | |
436 | + columnData.setOrdr(cellIndex); | |
437 | + if (StringUtil.isEmpty(originColumnName) == true) { | |
438 | + columnData.setDisplyColumnNm(COLUMN_NAME + cellIndex); | |
439 | + } else { | |
440 | + columnData.setDisplyColumnNm(originColumnName); | |
441 | + } | |
442 | + //해더 정보 세팅 | |
443 | + | |
444 | + columnData.setDataType(DataType.STRING); | |
445 | + if(cellIndex == 0) // url | |
446 | + { | |
447 | + columnData.setDbDataType("varchar"); | |
448 | + columnData.setDataSize(191); | |
449 | + columnData.setUniq(true); | |
450 | + }else if(cellIndex ==2) | |
451 | + { | |
452 | + columnData.setDbDataType("MEDIUMTEXT"); | |
453 | + }else { | |
454 | + columnData.setDbDataType("varchar"); | |
455 | + columnData.setDataSize(256); | |
456 | + } | |
457 | + | |
458 | + //컬럼 목록에 컬럼 정보 추가 | |
459 | + columnDatas.add(columnData); | |
460 | + } | |
461 | + | |
462 | + return columnDatas; | |
463 | + | |
464 | + } | |
465 | + | |
466 | + /** | |
467 | + * @author 최정우 | |
468 | + * @since 2019.11.19 | |
469 | + * | |
470 | + * DataTable에 존재하는 ColumnData에 대한 DataType Setting | |
471 | + */ | |
472 | + public static void setColumnDataType (DataTable dataTable) throws Exception { | |
473 | + | |
474 | + | |
475 | + //데이터가 없을 때 return | |
476 | + if (dataTable.getRowData() == null || dataTable.getRowData().size() == 0) return; | |
477 | + | |
478 | + //컬럼 목록 for문 | |
479 | + for(int cellIndex = 0; cellIndex < dataTable.getColumnDatas().size(); cellIndex++) { | |
480 | + //컬럼별 데이터의 데이터 타입 목록 (중복 등록은 방지하기 위해 Set으로 설정) | |
481 | + Set<DataType> dataTypes = new HashSet<DataType>(); | |
482 | + //데이터 목록 for문 | |
483 | + for(int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) { | |
484 | + //Cell 데이터 값 조회 | |
485 | + String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString(); | |
486 | + //Cell 데이터 값의 '데이터 타입' 조회 | |
487 | + | |
488 | + /* | |
489 | + * row > cell 데이터 값의 '데이터 타입' 지정 | |
490 | + * | |
491 | + * cell목록들 중 문자타입(STRING)이 존재하면, 해당 cell 전체를 문자타입(STRING)으로 바꿈 | |
492 | + * (즉, 데이터 타입을 체크하지 않음 -> cell전체다 데이터 타입을 체크해도 상관은 없음. 하지만 모든 cell을 다 체크해야되서 느려짐.) | |
493 | + */ | |
494 | +// DataType type = null; | |
495 | +// if (dataTypes.contains(DataType.STRING) == true) { | |
496 | +// type = DataType.STRING; | |
497 | +// } else { | |
498 | +// type = DataType.getDataType(value); | |
499 | +// } | |
500 | +// | |
501 | +// //Cell 데이터 값 및 타입 세팅 | |
502 | +// ColumnValue columnValue = new ColumnValue(); | |
503 | +// columnValue.setValue(value);//Cell에 조회된 '데이터 값' 세팅 | |
504 | +// columnValue.setDataType(type);//Cell에 조회된 '데이터 타입' 세팅 | |
505 | +// //dataTable에 Cell 데이터 값 및 타입 세팅 | |
506 | +// dataTable.getColumnDatas().get(cellIndex).getColumnValues().add(columnValue); | |
507 | +// | |
508 | +// //컬럼별 데이터의 '데이터 타입' 목록에 '데이터 타입' 입력 | |
509 | +// dataTypes.add(type); | |
510 | + }//row 목록 for문 끝 | |
511 | + | |
512 | + /*컬럼의 '데이터 타입' 세팅*/ | |
513 | + DataType columnDataType = getColumnDataType(dataTypes); | |
514 | + dataTable.getColumnDatas().get(cellIndex).setDataType(columnDataType); | |
515 | + /*컬럼의 '데이터 타입' 세팅*/ | |
516 | + | |
517 | + | |
518 | + /*컬럼의 'DB용 데이터 타입' 세팅*/ | |
519 | + if (columnDataType == DataType.STRING) {//문자열일 때 => 최대 길이 값 구하기 | |
520 | + //문자열 데이터 길이 | |
521 | + int size = 50; | |
522 | + | |
523 | + //컬럼의 열 데이터가 존재할 때 | |
524 | + List<ColumnValue> values = dataTable.getColumnDatas().get(cellIndex).getValues().stream().map(object -> (ColumnValue) object).collect(Collectors.toList()); | |
525 | + | |
526 | + for(int i = values.size() - 1 ; i >= 0 ; i--) { | |
527 | + if(values.get(i).getValue() == null) { | |
528 | + values.remove(i); | |
529 | + } | |
530 | + } | |
531 | + if (values.size() > 0) { | |
532 | + //최대 길이 값 구하기 | |
533 | + ColumnValue columnValue = values.stream().filter(s -> Objects.nonNull(s.getValue())).max((s1, s2) -> StringUtil.stringLength(s1.getValue()) - StringUtil.stringLength(s2.getValue())).get(); | |
534 | + //가장 긴 문자열의 글자수 | |
535 | + size = StringUtil.stringLength(columnValue.getValue()); | |
536 | + } | |
537 | + | |
538 | + | |
539 | + //테이블 생성시에 필요한 DB데이터 타입으로 Convert | |
540 | + String dbDataType = DataType.convertDbDataType(columnDataType, size); | |
541 | + | |
542 | + | |
543 | + //DB데이터 타입 입력 | |
544 | + dataTable.getColumnDatas().get(cellIndex).setDbDataType(dbDataType); | |
545 | + //DB데이터 타입이 varchar일 때 => 데이터 타입 크기 입력 | |
546 | + if (dbDataType.equals("varchar")) { | |
547 | +// if (size < SystemCode.DEFAULT_VARCHAR_SIZE) { | |
548 | +// size = SystemCode.DEFAULT_VARCHAR_SIZE; | |
549 | +// } | |
550 | + dataTable.getColumnDatas().get(cellIndex).setDataSize(size);//데이터 타입 크기 입력 | |
551 | + } | |
552 | + } else {//문자열이 아닐 때 => DB데이터 타입 입력 | |
553 | + dataTable.getColumnDatas().get(cellIndex).setDbDataType(DataType.convertDbDataType(columnDataType, null)); | |
554 | + }/*컬럼의 'DB용 데이터 타입' 세팅*/ | |
555 | + | |
556 | + }//컬럼 목록 for문 끝 | |
557 | + | |
558 | + dataTable.getCheckMessage().setSuccess(true); | |
559 | + } | |
560 | + | |
561 | + /** | |
562 | + * @author 최정우 | |
563 | + * @since 2019.11.19 | |
564 | + * | |
565 | + * DataTable에 있는 rowData를 columnData로 Convert후, DataTable로 리턴 | |
566 | + */ | |
567 | + public static DataTable columnDataCreateByFile (DataTable dataTable) throws Exception { | |
568 | + dataTable.setColumnDatas(columnDataCreateByFile(dataTable.getRowData())); //????? | |
569 | + return dataTable; | |
570 | + } | |
571 | + | |
572 | + /** | |
573 | + * @author 최정우 | |
574 | + * @since 2019.11.19 | |
575 | + * | |
576 | + * rowData List<List<String>> -> DataTable로 Convert | |
577 | + */ | |
578 | + public static DataTable dataTableCreate (List<List<Object>> rowData, String title) throws Exception { | |
579 | + DataTable dataTable = dataTableCreate(rowData); | |
580 | + dataTable.setDatasetSj(title); | |
581 | + return dataTable; | |
582 | + } | |
583 | + | |
584 | + /** | |
585 | + * @author 최정우 | |
586 | + * @since 2019.11.19 | |
587 | + * | |
588 | + * rowData List<List<String>> -> DataTable로 Convert (단, 데이터명이 없음) | |
589 | + */ | |
590 | + public static DataTable dataTableCreate (List<List<Object>> rowData) throws Exception { | |
591 | + DataTable dataTable = new DataTable(); | |
592 | + dataTable.setColumnDatas(columnDataCreateByFile(rowData)); | |
593 | + return dataTable; | |
594 | + } | |
595 | + | |
596 | + /** | |
597 | + * @author 최정우 | |
598 | + * @since 2019.11.19 | |
599 | + * | |
600 | + * rowData cell의 최대 크기 (빈공간 채우기 위함) | |
601 | + */ | |
602 | + public static int rowDataCellMaxSize (List<List<Object>> rowData) throws Exception { | |
603 | + int cellMaxSize = 0; | |
604 | + for(int rowIndex = 0; rowIndex < rowData.size(); rowIndex++) { | |
605 | + int cellSize = rowData.get(rowIndex).size(); | |
606 | + if (cellMaxSize < cellSize) { | |
607 | + cellMaxSize = cellSize; | |
608 | + } | |
609 | + } | |
610 | + | |
611 | + return cellMaxSize; | |
612 | + } | |
613 | + | |
614 | + /** | |
615 | + * @author 최정우 | |
616 | + * @since 2019.11.19 | |
617 | + * | |
618 | + * rowData cell의 빈공간 채우기 (cellMaxSize 크기 만큼) | |
619 | + */ | |
620 | + public static void rowDataCellInfill (List<List<Object>> rowData, int cellMaxSize) throws Exception { | |
621 | + for(int rowIndex = 0; rowIndex < rowData.size(); rowIndex++) { | |
622 | + int addSize = cellMaxSize - rowData.get(rowIndex).size(); | |
623 | + for(int cellIndex = 0; cellIndex < addSize; cellIndex++) { | |
624 | + rowData.get(rowIndex).add(null); | |
625 | + } | |
626 | + } | |
627 | + } | |
628 | + | |
629 | + /** | |
630 | + * @author 최정우 | |
631 | + * @since 2019.11.27 | |
632 | + * | |
633 | + * column의 데이터 타입 지정 | |
634 | + */ | |
635 | + public static DataType getColumnDataType (Set<DataType> datatypes) throws Exception { | |
636 | + if (datatypes.contains(DataType.STRING)) { | |
637 | + return DataType.STRING; | |
638 | + } else if (datatypes.contains(DataType.DATE)) { | |
639 | + if (datatypes.contains(DataType.DOUBLE) || datatypes.contains(DataType.LONG)) { | |
640 | + return DataType.STRING; | |
641 | + } else { | |
642 | + return DataType.DATE; | |
643 | + } | |
644 | + } else if (datatypes.contains(DataType.DOUBLE)) { | |
645 | + return DataType.DOUBLE; | |
646 | + } else if (datatypes.contains(DataType.LONG)) { | |
647 | + return DataType.LONG; | |
648 | + } else { | |
649 | + return DataType.STRING; | |
650 | + } | |
651 | + } | |
652 | + | |
653 | + /** | |
654 | + * @author 최정우 | |
655 | + * @since 2019.11.27 | |
656 | + * | |
657 | + * 데이터 셋의 컬럼의 데이터 타입을 통해, 데이터 셋의 데이터 타입 지정 | |
658 | + */ | |
659 | +// public static DatasetDataType getDatasetDataType (List<ColumnData> columnDatas) throws Exception { | |
660 | +// for (int j = 0; j < columnDatas.size(); j++) { | |
661 | +// if (columnDatas.get(j).getDataType() != DataType.STRING) { | |
662 | +// return DatasetDataType.NUMBER; | |
663 | +// } | |
664 | +// } | |
665 | +// | |
666 | +// return DatasetDataType.TEXT; | |
667 | +// | |
668 | +// }????? | |
669 | + | |
670 | + | |
671 | + | |
672 | + /** | |
673 | + * @author 김성원 | |
674 | + * @since 2019.12.04 | |
675 | + * | |
676 | + * double 형태의 List<ColumnValue> 데이터 최대 최소 평균 | |
677 | + */ | |
678 | + public static ColumnData setDoubleCalculation (ColumnData columnData , DataTable dataTable) throws Exception { | |
679 | + columnData.getValues().sort(null); | |
680 | + | |
681 | + int index = 0; | |
682 | + Object min = 0; | |
683 | + Object max = 0; | |
684 | + | |
685 | + for(int i = 0 ; i < dataTable.getColumnDatas().size() ; i++) { | |
686 | + if(dataTable.getColumnDatas().get(i).getColumnNm().equals(columnData.getColumnNm())) { | |
687 | + index = i; | |
688 | + break; | |
689 | + } | |
690 | + } | |
691 | + | |
692 | + final int indx = index; | |
693 | + | |
694 | + | |
695 | + int totalSize = dataTable.getRowData().size(); | |
696 | + | |
697 | + //List<ColumnValue> nonNullColumnValues = columnData.getColumnValues().stream().filter(a -> a.getValue() != null).collect(Collectors.toList()); | |
698 | + | |
699 | + List<List<Object>> dataList = dataTable.getRowData().stream().filter(x1 -> x1.get(indx) != null).collect(Collectors.toList()); | |
700 | + | |
701 | + if (dataList.size() > 0) { | |
702 | + | |
703 | + int nonNullSize = dataList.size(); | |
704 | + | |
705 | + columnData.setMin(CommonUtil.parseDouble(dataList.get(0).get(indx))); | |
706 | + columnData.setMax(CommonUtil.parseDouble(dataList.get(nonNullSize-1).get(indx))); | |
707 | + | |
708 | + if(nonNullSize % 2 == 0) { | |
709 | + columnData.setMedian((CommonUtil.parseDouble(dataList.get(nonNullSize / 2).get(indx)) + CommonUtil.parseDouble(dataList.get(nonNullSize / 2 -1 ).get(indx))) / 2); | |
710 | + }else { | |
711 | + columnData.setMedian(CommonUtil.parseDouble(dataList.get(nonNullSize / 2).get(indx))); | |
712 | + } | |
713 | + | |
714 | + Object sum = dataList.stream().mapToDouble(mapper -> CommonUtil.parseDouble(mapper.get(indx))).sum(); | |
715 | + | |
716 | + columnData.setSum(sum); | |
717 | + | |
718 | + columnData.setMean(Math.round((((double) sum / nonNullSize)*100)/100.0)); | |
719 | + | |
720 | + columnData.setNullCount(totalSize - nonNullSize); | |
721 | + } else { | |
722 | + columnData.setMin("0"); | |
723 | + columnData.setMax("0"); | |
724 | + columnData.setSum(0); | |
725 | + columnData.setMean(0.0); | |
726 | + columnData.setMedian("0"); | |
727 | + columnData.setNullCount(0); | |
728 | + } | |
729 | + | |
730 | + return columnData; | |
731 | + } | |
732 | + | |
733 | + /** | |
734 | + * @author 김성원 | |
735 | + * @since 2019.12.04 | |
736 | + * | |
737 | + * 데이터 테이블의 DATAROW를 확인하여 최대최소 저장 | |
738 | + */ | |
739 | + public static DataTable setRowDataCalculation (DataTable table) throws Exception { | |
740 | + | |
741 | + // 컬럼데이터 전체 최소 최대 계산 | |
742 | + int index = 0; | |
743 | + for(ColumnData columnData :table.getColumnDatas()) { | |
744 | + | |
745 | + if(columnData.getDataTy().equals(DataType.DOUBLE)) { | |
746 | + table.getColumnDatas().set(index,setDoubleCalculation(table.getCoulmnDataByCoulmnIndex(index),table)); | |
747 | + table.getColumnDatas().get(index).getValues().clear(); | |
748 | + }else if(columnData.getDataTy().equals(DataType.LONG)) { | |
749 | + table.getColumnDatas().set(index,setLongCalculation(table.getCoulmnDataByCoulmnIndex(index),table)); | |
750 | + table.getColumnDatas().get(index).getValues().clear(); | |
751 | + } | |
752 | + index++; | |
753 | + } | |
754 | + | |
755 | + | |
756 | + | |
757 | + return table; | |
758 | + } | |
759 | + | |
760 | + | |
761 | + /** | |
762 | + * @author 김성원 | |
763 | + * @since 2019.12.04 | |
764 | + * | |
765 | + * Long 형태의 List<ColumnValue> 데이터 최대 최소 평균 | |
766 | + */ | |
767 | + public static ColumnData setLongCalculation (ColumnData columnData, DataTable dataTable) throws Exception { | |
768 | + columnData.getValues().sort(null); | |
769 | + | |
770 | + int index = 0; | |
771 | + Object min = 0; | |
772 | + Object max = 0; | |
773 | + | |
774 | + for(int i = 0 ; i < dataTable.getColumnDatas().size() ; i++) { | |
775 | + if(dataTable.getColumnDatas().get(i).getColumnNm().equals(columnData.getColumnNm())) { | |
776 | + index = i; | |
777 | + break; | |
778 | + } | |
779 | + } | |
780 | + | |
781 | + final int indx = index; | |
782 | + | |
783 | + | |
784 | + int totalSize = dataTable.getRowData().size(); | |
785 | + | |
786 | + List<List<Object>> dataList = dataTable.getRowData().stream().filter(x1 -> x1.get(indx) != null).collect(Collectors.toList()); | |
787 | + | |
788 | + | |
789 | + if (dataList.size() > 0) { | |
790 | + | |
791 | + int nonNullSize = dataList.size(); | |
792 | + | |
793 | + if(nonNullSize != 0) { | |
794 | + columnData.setMin(CommonUtil.parseLong(dataList.get(0).get(indx))); | |
795 | + columnData.setMax(CommonUtil.parseLong(dataList.get(nonNullSize-1).get(indx))); | |
796 | + if(nonNullSize % 2 == 0) { | |
797 | + columnData.setMedian((CommonUtil.parseLong(dataList.get(nonNullSize / 2).get(indx)) + CommonUtil.parseLong(dataList.get(nonNullSize / 2 -1 ).get(indx))) / 2); | |
798 | + }else { | |
799 | + columnData.setMedian(CommonUtil.parseLong(dataList.get(nonNullSize / 2).get(indx))); | |
800 | + } | |
801 | + | |
802 | + Object sum = dataList.stream().mapToLong(mapper -> CommonUtil.parseLong(mapper.get(indx))).sum(); | |
803 | + | |
804 | + columnData.setSum(sum); | |
805 | + | |
806 | + columnData.setMean(Math.round((( Double.parseDouble(sum.toString()) / nonNullSize)*100)/100.0)); | |
807 | + | |
808 | + columnData.setNullCount(totalSize - nonNullSize); | |
809 | + }else { | |
810 | + columnData.setMin("0"); | |
811 | + columnData.setMax("0"); | |
812 | + columnData.setSum(0); | |
813 | + columnData.setMean(0.0); | |
814 | + columnData.setMedian("0"); | |
815 | + columnData.setNullCount(0); | |
816 | + } | |
817 | + } else { | |
818 | + columnData.setMin("0"); | |
819 | + columnData.setMax("0"); | |
820 | + columnData.setSum(0); | |
821 | + columnData.setMean(0.0); | |
822 | + columnData.setMedian("0"); | |
823 | + columnData.setNullCount(0); | |
824 | + } | |
825 | + | |
826 | + return columnData; | |
827 | + } | |
828 | + | |
829 | + /** | |
830 | + * @author 김성원 | |
831 | + * @since 2019.12.04 | |
832 | + * | |
833 | + * double 형태의 List<ColumnValue> 문자열 최빈, 최다, 리스트구하기 | |
834 | + */ | |
835 | + public static ColumnData setStringCalculation (ColumnData columnData, DataTable dataTable) throws Exception { | |
836 | + | |
837 | + | |
838 | + columnData.setLeast("-"); | |
839 | + columnData.setMode("-"); | |
840 | + columnData.setNullCount(0); | |
841 | + int index = 0; | |
842 | + | |
843 | + for(int i = 0 ; i < dataTable.getColumnDatas().size() ; i++) { | |
844 | + if(dataTable.getColumnDatas().get(i).getColumnNm().equals(columnData.getColumnNm())) { | |
845 | + index = i; | |
846 | + break; | |
847 | + } | |
848 | + } | |
849 | + | |
850 | + final int indx = index; | |
851 | + | |
852 | + | |
853 | + int totalSize = dataTable.getRowData().size(); | |
854 | + | |
855 | + List<List<Object>> dataList = dataTable.getRowData().stream().filter(x1 -> x1.get(indx) != null).collect(Collectors.toList()); | |
856 | + | |
857 | + | |
858 | + | |
859 | + // List<ColumnValue> nonNullColumnValues = columnData.getColumnValues().stream().filter(a -> a.getValue() != null).collect(Collectors.toList()); | |
860 | + | |
861 | + if (dataList.size() > 0) { | |
862 | + | |
863 | + int nonNullSize = dataList.size(); | |
864 | + | |
865 | + final Map<String, Integer> counter = new HashMap<String, Integer>(); | |
866 | + | |
867 | + // 언어별 카운트 | |
868 | + for( List<Object> value : dataList ){ | |
869 | + | |
870 | + counter.put(StringUtil.toString(value.get(indx)), 1 + (counter.containsKey(StringUtil.toString(value.get(indx))) ? counter.get(StringUtil.toString(value.get(indx))) : 0)); | |
871 | + } | |
872 | + | |
873 | + // 정렬을 위한 LinkedList | |
874 | + List<Map.Entry<String, Integer>> list = new LinkedList<>(counter.entrySet()); | |
875 | + | |
876 | + Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() { | |
877 | + @Override | |
878 | + public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { | |
879 | + int comparision = (o1.getValue() - o2.getValue()) * -1; | |
880 | + return comparision == 0 ? o1.getKey().compareTo(o2.getKey()) : comparision; | |
881 | + } | |
882 | + }); | |
883 | + | |
884 | + | |
885 | + for(Map.Entry<String, Integer> temp : list) { | |
886 | + columnData.getValues().add(new ColumnValue(temp.getKey().trim(), DataType.STRING, temp.getValue())); | |
887 | + } | |
888 | + | |
889 | + if(list.size() > 0) { | |
890 | + columnData.setLeast(list.get(0).getKey()); | |
891 | + columnData.setMode(list.get(list.size()-1).getKey()); | |
892 | + } | |
893 | + | |
894 | + columnData.setNullCount(totalSize - nonNullSize); | |
895 | + } | |
896 | + | |
897 | + return columnData; | |
898 | + } | |
899 | + | |
900 | + | |
901 | + /** | |
902 | + * @author 김성원 | |
903 | + * @since 2021.11.04 | |
904 | + * | |
905 | + * List<Map<String,Object>>형태의 데이터를 DataTable로 반환 | |
906 | + */ | |
907 | + public static DataTable setMaptoDataTable (List<Map<String,Object>> mapData) throws Exception { | |
908 | + | |
909 | + DataTable dataTable = new DataTable(); | |
910 | + | |
911 | + Map<String,List<String>> columnDataMap = new HashMap<String,List<String>>(); | |
912 | + | |
913 | + // columnData 맵 데이터 생성 | |
914 | + for(Map<String,Object> temp : mapData) { | |
915 | + for( Map.Entry<String, Object> elem : temp.entrySet() ){ | |
916 | + if(columnDataMap.get(elem.getKey()) == null){ | |
917 | + columnDataMap.put(elem.getKey(), new ArrayList<String>()); | |
918 | + columnDataMap.get(elem.getKey()).add(elem.getKey()); | |
919 | + } | |
920 | + try { | |
921 | + columnDataMap.get(elem.getKey()).add(elem.getValue().toString()); | |
922 | + }catch(Exception e) { | |
923 | + columnDataMap.get(elem.getKey()).add("".toString()); | |
924 | + } | |
925 | + } | |
926 | + } | |
927 | + | |
928 | + | |
929 | + | |
930 | + for(Map.Entry<String, List<String>> elem : columnDataMap.entrySet()){ | |
931 | + List<Object> elemData = new ArrayList<>(); | |
932 | + elemData.add(elem.getValue()); | |
933 | + dataTable.getRowData().add(elemData); | |
934 | + } | |
935 | + | |
936 | + dataTable.setRowData(dataTable.matrixChange()); | |
937 | + | |
938 | + // rowData의 최대 Cell 크기 | |
939 | + int cellMaxSize = DataUtil.rowDataCellMaxSize(dataTable.getRowData()); | |
940 | + | |
941 | + // rowData cell의 빈공간 채우기 | |
942 | + DataUtil.rowDataCellInfill(dataTable.getRowData(), cellMaxSize); | |
943 | + | |
944 | + // 헤더 정보 가지고오기 | |
945 | + List<Object> headers = dataTable.getRowData().get(0); | |
946 | + | |
947 | + // 세팅될 컬럼 정보 | |
948 | + List<ColumnData> columnDatas = new ArrayList<ColumnData>(); | |
949 | + for (int cellIndex = 0; cellIndex < headers.size(); cellIndex++) { | |
950 | + ColumnData columnData = new ColumnData(); | |
951 | + | |
952 | + // 헤더명 (컬럼명) | |
953 | + String originColumnName = headers.get(cellIndex).toString(); | |
954 | + | |
955 | + // 해당 열에 행데이터가 1개라도 존재하는지 체크 (헤더 데이터 포함해서 체크) | |
956 | + boolean isCellDataExist = false; | |
957 | + | |
958 | + // 해당 열의 행 데이터 검사 시작 | |
959 | + for (int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) { | |
960 | + String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString(); | |
961 | + | |
962 | + // 값이 있으면, -> 검사 종료 | |
963 | + if (StringUtil.isEmpty(value) == false) { | |
964 | + isCellDataExist = true; | |
965 | + break; | |
966 | + } | |
967 | + } | |
968 | + | |
969 | + // 해당 열에 데이터가 한개라도 존재할 때 -> 컬럼 생성 | |
970 | + if (isCellDataExist == true) { | |
971 | + /* 컬럼 생성 */ | |
972 | + columnData.setOrginlColumnNm(originColumnName); | |
973 | + columnData.setDisplyColumnNm(originColumnName); | |
974 | + columnDatas.add(columnData); | |
975 | + } else {// 해당 열에 데이터가 없을 때 -> 해당 열 데이터 전체 삭제 | |
976 | + /* 해당 열 데이터 전체 삭제 */ | |
977 | + for (int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) { | |
978 | + dataTable.getRowData().get(rowIndex).remove(cellIndex); | |
979 | + } | |
980 | + /* 해당 열 데이터 전체 삭제 후, 현재 열 Index 1 줄이기 */ | |
981 | + cellIndex--; | |
982 | + } | |
983 | + } | |
984 | + | |
985 | + // DataTable의 컬럼정보 세팅 | |
986 | + dataTable.setColumnDatas(columnDatas); | |
987 | + | |
988 | + // 컬럼 데이터 세팅 후, 행별 데이터에 헤더값(0번 index) 제거 | |
989 | + | |
990 | + | |
991 | + dataTable.getRowData().remove(0); | |
992 | + return dataTable; | |
993 | + } | |
994 | + | |
995 | + /** | |
996 | + * @author 김성원 | |
997 | + * @since 2021.11.04 | |
998 | + * | |
999 | + * 컬럼데이터 업데이트 가능여부 | |
1000 | + */ | |
1001 | + /* | |
1002 | + public static Map<String,Object> checkCoulmnDataInsert(ColumnData origin, List<Object> data) { | |
1003 | + Map<String,Object> result = new HashMap<String,Object>(); | |
1004 | + result.put("result", true); | |
1005 | + result.put("resultMassage", "정상작동"); | |
1006 | + DataType type = origin.getDataType(); | |
1007 | + int count = 0; | |
1008 | + for(Object item : data) { | |
1009 | + count++; | |
1010 | + boolean check = true; | |
1011 | + if(type.equals(DataType.STRING)) { | |
1012 | + check = item instanceof String; | |
1013 | + if(item.toString().length() > origin.getSize()) { | |
1014 | + check = false; | |
1015 | + result.put("result", false); | |
1016 | + result.put("resultMassage", "["+origin.getDisplayColumnName() + "]의 데이터 크기("+origin.getSize()+")보다 큽니다. \r\n" | |
1017 | + + "데이터 : [" + item.toString() +"]의 크기("+item.toString().length()+")"); | |
1018 | + } | |
1019 | + }else if(type.equals(DataType.INT)) { | |
1020 | + try { | |
1021 | + Integer.parseInt(item.toString()); | |
1022 | + }catch(Exception e) { | |
1023 | + check = false; | |
1024 | + } | |
1025 | + }else if(type.equals(DataType.LONG)) { | |
1026 | + try { | |
1027 | + Long.parseLong(item.toString()); | |
1028 | + }catch(Exception e) { | |
1029 | + check = false; | |
1030 | + } | |
1031 | + }else if(type.equals(DataType.DOUBLE)) { | |
1032 | + try { | |
1033 | + Double.parseDouble(item.toString()); | |
1034 | + }catch(Exception e) { | |
1035 | + check = false; | |
1036 | + } | |
1037 | + }else if(type.equals(DataType.DATE) || type.equals(DataType.DATETIME)) { | |
1038 | + check = item instanceof Date; | |
1039 | + } | |
1040 | + | |
1041 | + if(check == false) { | |
1042 | + result.put("result", false); | |
1043 | + if(result.get("resultMassage").equals("정상작동")) { | |
1044 | + result.put("resultMassage", "["+origin.getDisplayColumnName() + "]의 데이터 형태가 ["+type+"]와 일치하지 안습니다. \r\n" | |
1045 | + + "데이터 : (" + item.toString() +")"); | |
1046 | + } | |
1047 | + } | |
1048 | + if(count > 1000) { | |
1049 | + break; | |
1050 | + } | |
1051 | + } | |
1052 | + | |
1053 | + return result; | |
1054 | + } | |
1055 | + */ | |
1056 | + | |
1057 | + /** | |
1058 | + * @author 김성원 | |
1059 | + * @since 2021.11.04 | |
1060 | + * | |
1061 | + * 컬럼데이터 업데이트 가능여부 | |
1062 | + */ | |
1063 | + public static Map<String,Object> checkCoulmnDataInserts(ColumnData origin, int index, List<List<String>> data) { | |
1064 | + Map<String,Object> result = new HashMap<String,Object>(); | |
1065 | + result.put("result", true); | |
1066 | + result.put("resultMassage", "정상작동"); | |
1067 | + DataType type = origin.getDataTy(); | |
1068 | + int count = 0; | |
1069 | + | |
1070 | + for(List<String> listItem : data) { | |
1071 | + count++; | |
1072 | + boolean check = true; | |
1073 | + if(listItem.size() > index && !StringUtil.isEmpty(listItem.get(index)) ) { | |
1074 | + if(type.equals(DataType.STRING)) { | |
1075 | + if(listItem.get(index).length() > origin.getDataSize()) { | |
1076 | + check = false; | |
1077 | + result.put("result", false); | |
1078 | + result.put("resultMassage", "["+origin.getDisplyColumnNm() + "]의 데이터 크기("+origin.getDataSize()+")보다 큽니다. \r\n" | |
1079 | + + "데이터 : [" +listItem.get(index) +"]의 크기("+ listItem.get(index).length()+")"); | |
1080 | + } | |
1081 | + }else if(type.equals(DataType.INT)) { | |
1082 | + try { | |
1083 | + Integer.parseInt(listItem.get(index)); | |
1084 | + }catch(Exception e) { | |
1085 | + check = false; | |
1086 | + } | |
1087 | + }else if(type.equals(DataType.LONG)) { | |
1088 | + try { | |
1089 | + Long.parseLong(listItem.get(index)); | |
1090 | + }catch(Exception e) { | |
1091 | + check = false; | |
1092 | + } | |
1093 | + }else if(type.equals(DataType.DOUBLE)) { | |
1094 | + try { | |
1095 | + Double.parseDouble(listItem.get(index)); | |
1096 | + }catch(Exception e) { | |
1097 | + check = false; | |
1098 | + } | |
1099 | + }else if(type.equals(DataType.DATE) || type.equals(DataType.DATETIME)) { | |
1100 | + // 체크필요 // | |
1101 | + | |
1102 | + //check = item instanceof Date; | |
1103 | + } | |
1104 | + } | |
1105 | + if(count > 1000) { | |
1106 | + break; | |
1107 | + } | |
1108 | + | |
1109 | + } | |
1110 | + | |
1111 | + return result; | |
1112 | + } | |
1113 | + | |
1114 | + | |
1115 | + public static Map<String, Object> getJsonData(DatasetPost dp) { | |
1116 | + | |
1117 | + Map<String,Object> resultData = new HashMap<String,Object>(); | |
1118 | + | |
1119 | + resultData.put("id", dp.getDataset_post_id()); | |
1120 | + resultData.put("title", dp.getPost_sj()); | |
1121 | + resultData.put("category", dp.getCategoryTitle()); | |
1122 | + if(StringUtil.isEmpty(dp.getOrigin())) { | |
1123 | + resultData.put("orgName", "관리자"); | |
1124 | + }else { | |
1125 | + resultData.put("orgName", dp.getOrigin()); | |
1126 | + } | |
1127 | + | |
1128 | + resultData.put("createDate", dp.getCreat_dt()); | |
1129 | + resultData.put("updateDate", dp.getUpdt_dt()); | |
1130 | + resultData.put("requestCount", dp.getRdcnt()); | |
1131 | +// resultData.put("status", dp.getStatus());?? | |
1132 | + if(StringUtil.isEmpty(dp.getFile_manager_id())) { | |
1133 | + resultData.put("fileExt", "0"); | |
1134 | + }else { | |
1135 | + resultData.put("fileExt", "1"); | |
1136 | + } | |
1137 | + | |
1138 | + /*혜민 추가 220428*/ | |
1139 | + resultData.put("datasetId",dp.getDataset_id()); | |
1140 | + /*혜민 추가 끝 220428*/ | |
1141 | + return resultData; | |
1142 | + } | |
1143 | + | |
1144 | + | |
1145 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/util/SeolAPIUtil.java
... | ... | @@ -0,0 +1,392 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.api.util; | |
2 | + | |
3 | +import java.io.BufferedReader; | |
4 | +import java.io.BufferedWriter; | |
5 | +import java.io.ByteArrayInputStream; | |
6 | +import java.io.InputStreamReader; | |
7 | +import java.io.OutputStream; | |
8 | +import java.io.OutputStreamWriter; | |
9 | +import java.net.HttpURLConnection; | |
10 | +import java.net.URL; | |
11 | +import java.text.DateFormat; | |
12 | +import java.text.SimpleDateFormat; | |
13 | +import java.util.ArrayList; | |
14 | +import java.util.Calendar; | |
15 | +import java.util.Date; | |
16 | +import java.util.HashMap; | |
17 | +import java.util.List; | |
18 | +import java.util.Map; | |
19 | + | |
20 | +import javax.xml.parsers.DocumentBuilder; | |
21 | +import javax.xml.parsers.DocumentBuilderFactory; | |
22 | + | |
23 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.DataType; | |
24 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
25 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
26 | +import org.w3c.dom.Document; | |
27 | +import org.w3c.dom.NodeList; | |
28 | + | |
29 | +/** | |
30 | + * @author 최민식 | |
31 | + * @since 2020.08.12 | |
32 | + * | |
33 | + * 세올 데이터 | |
34 | + */ | |
35 | +public class SeolAPIUtil { | |
36 | + // 인코딩타입 | |
37 | + private final static String CHARSET = "UTF-8"; | |
38 | + // 연계ID | |
39 | + private final static String IFID = "SOINN00001"; | |
40 | + // 요청기관코드7자리 | |
41 | + private final static String SRCORGCD = "5110000"; //상주시 | |
42 | + // 응답기관코드7자리 | |
43 | + private final static String TGTORGCD = "5110000"; //상주시 | |
44 | + | |
45 | + public static Map<String, Object> getParam () { | |
46 | + // 현재 날짜 호출 | |
47 | + SimpleDateFormat format1 = new SimpleDateFormat("yyyyMMdd"); | |
48 | + Date nowDate = new Date(); | |
49 | + String nowDate_format = format1.format(nowDate); | |
50 | + | |
51 | + // 하루전 날짜 호출 | |
52 | + Calendar cal = Calendar.getInstance(); | |
53 | + DateFormat df = new SimpleDateFormat("yyyyMMdd"); | |
54 | + Date date = null; | |
55 | + cal.add(Calendar.DATE, -1); | |
56 | + String aDayAgo = df.format(cal.getTime()); | |
57 | + | |
58 | + Map<String, Object> param = new HashMap<>(); | |
59 | + | |
60 | + /** 민원목록정보 정보 **/ | |
61 | + Map<String, Object> detailInfo11 = new HashMap<>(); | |
62 | + // 컬럼 정보 | |
63 | + List<ColumnData> columnDatas11 = new ArrayList<ColumnData>(); | |
64 | + columnDatas11.add(new ColumnData("dpp_user_posit_code", "처리담당자직급코드", DataType.STRING)); | |
65 | + columnDatas11.add(new ColumnData("take_dep_nm", "접수부서명", DataType.STRING)); | |
66 | + columnDatas11.add(new ColumnData("deal_plan_daycnt", "처리일수", DataType.STRING)); | |
67 | + columnDatas11.add(new ColumnData("mw_kd_nm", "민원유형", DataType.STRING)); | |
68 | + columnDatas11.add(new ColumnData("deal_plan_ymd", "처리예정일", DataType.STRING)); | |
69 | + columnDatas11.add(new ColumnData("restamt_rtn", "잔액반송금액", DataType.STRING)); | |
70 | + columnDatas11.add(new ColumnData("mw_pps_getr_yn", "수령여부", DataType.STRING)); | |
71 | + columnDatas11.add(new ColumnData("tot_cnt", "총건수", DataType.STRING)); | |
72 | + columnDatas11.add(new ColumnData("real_deal_tm", "처리시간", DataType.STRING)); | |
73 | + columnDatas11.add(new ColumnData("fee_recpt_se_nm", "수납구분", DataType.STRING)); | |
74 | + columnDatas11.add(new ColumnData("deal_plan_tm", "처리예정시간", DataType.STRING)); | |
75 | + columnDatas11.add(new ColumnData("reg_dt", "등록일시", DataType.STRING)); | |
76 | + columnDatas11.add(new ColumnData("main_deal_dep_code", "처리부서코드", DataType.STRING)); | |
77 | + columnDatas11.add(new ColumnData("take_confrm_code", "접수확인여부(접수구분)", DataType.STRING)); | |
78 | + columnDatas11.add(new ColumnData("take_se_nm", "민원접수구분", DataType.STRING)); | |
79 | + columnDatas11.add(new ColumnData("take_dt", "접수일시", DataType.STRING)); | |
80 | + columnDatas11.add(new ColumnData("mw_take_no", "접수번호", DataType.STRING, true)); | |
81 | + columnDatas11.add(new ColumnData("take_dep_code", "접수부서코드", DataType.STRING)); | |
82 | + columnDatas11.add(new ColumnData("sndmny_am", "송금액", DataType.STRING)); | |
83 | + columnDatas11.add(new ColumnData("appl_mwin_se_nm", "신청인구분", DataType.STRING)); | |
84 | + columnDatas11.add(new ColumnData("mw_afr_shtnm", "민원명", DataType.STRING)); | |
85 | + columnDatas11.add(new ColumnData("deal_se_nm", "처리구분", DataType.STRING)); | |
86 | + columnDatas11.add(new ColumnData("row_no", "로우넘", DataType.STRING)); | |
87 | + columnDatas11.add(new ColumnData("main_deal_dep_nm", "처리부서명", DataType.STRING)); | |
88 | + columnDatas11.add(new ColumnData("mw_notes", "민원요지", DataType.STRING)); | |
89 | + columnDatas11.add(new ColumnData("real_deal_ymd", "처리일자", DataType.STRING)); | |
90 | + columnDatas11.add(new ColumnData("take_user_posit_nm", "접수자직급명", DataType.STRING)); | |
91 | + columnDatas11.add(new ColumnData("dpp_user_posit_nm", "처리담당자직급명", DataType.STRING)); | |
92 | + columnDatas11.add(new ColumnData("take_user_posit_code", "접수자직급코드", DataType.STRING)); | |
93 | + columnDatas11.add(new ColumnData("mw_se_nm", "민원구분", DataType.STRING)); | |
94 | + detailInfo11.put("columnDatas", columnDatas11); | |
95 | + detailInfo11.put("requestInfo", "<dataList><data>"+nowDate_format+"</data></dataList>" | |
96 | + + "<dataList><data>"+aDayAgo+"</data></dataList>" | |
97 | + + "<dataList><data>1</data></dataList>" | |
98 | + + "<dataList><data>100</data></dataList>"); | |
99 | + param.put("5110000SOI001", detailInfo11); //상주시 | |
100 | + /** 민원목록정보 정보 **/ | |
101 | + return param; | |
102 | + } | |
103 | + | |
104 | + /** | |
105 | + * 쿼리종류 분류 | |
106 | + */ | |
107 | + public DataTable getSeolMain(String url, String apikey) { | |
108 | + // 빈 객체 생성 | |
109 | + DataTable dataTable; | |
110 | + if(apikey.equals("5110000SOI001") ) { // 상주시 민원 | |
111 | + Map<String, Object> param = (Map<String, Object>) getParam().get(apikey); | |
112 | + dataTable = getSeolData(url, apikey, param); | |
113 | + // 현재 날짜 호출 | |
114 | + SimpleDateFormat format1 = new SimpleDateFormat("yyyyMMdd"); | |
115 | + Date nowDate = new Date(); | |
116 | + String nowDate_format = format1.format(nowDate); | |
117 | + // 하루전 날짜 호출 | |
118 | + Calendar cal = Calendar.getInstance(); | |
119 | + DateFormat df = new SimpleDateFormat("yyyyMMdd"); | |
120 | + Date date = null; | |
121 | + cal.add(Calendar.DATE, -1); | |
122 | + String aDayAgo = df.format(cal.getTime()); | |
123 | + String requestInfo = "<dataList><data>"+aDayAgo+"</data></dataList>" | |
124 | + + "<dataList><data>"+nowDate_format+"</data></dataList>" | |
125 | + + "<dataList><data>1</data></dataList>" | |
126 | + + "<dataList><data>100</data></dataList>"; | |
127 | + param.put("requestInfo", requestInfo); | |
128 | + // 페이지가 1이상일 경우 추가로 합쳐야할 정보들 | |
129 | + DataTable dataTable_ = getSeolData(url, apikey, param); | |
130 | + // 데이터 추가 | |
131 | + for(int j = 0; j < dataTable_.getRowData().size(); j++) { | |
132 | + System.out.println("j 소환 : " + j); | |
133 | + dataTable.getRowData().add(dataTable_.getRowData().get(j)); | |
134 | + } | |
135 | + } else { | |
136 | + // ,구분자 짜르기 | |
137 | + String[] apikeyList = apikey.split(","); | |
138 | + // 해당 정보의 갯수 호출 | |
139 | + int cnt = getSeolDataCnt(url, apikeyList[1]); | |
140 | + // 페이징 갯수 | |
141 | + int pagingCnt = (int) Math.ceil((double) cnt / 200); | |
142 | + // 페이징 갯수가 1이상일 경우 | |
143 | + Map<String, Object> param = (Map<String, Object>) getParam().get(apikeyList[0]); | |
144 | + // 페이징 갯수가 1이상일 경우 | |
145 | + if(pagingCnt > 1) { | |
146 | + dataTable = getSeolData(url, apikeyList[0], param); | |
147 | + for(int i = 1; i <= pagingCnt; i++) { | |
148 | + System.out.println("i 값을 알아보자 : " + i); | |
149 | + // 파라미터값 호출(쿼리문에 사용되는) | |
150 | + String requestInfo = (String) param.get("requestInfo"); | |
151 | + // 페이징 증가 | |
152 | + requestInfo = replaceLast(requestInfo, Integer.toString(i), Integer.toString(i+1)); | |
153 | + // 변경된 파라미터값 삽입 | |
154 | + param.put("requestInfo", requestInfo); | |
155 | + | |
156 | + // 페이지가 1이상일 경우 추가로 합쳐야할 정보들 | |
157 | + DataTable dataTable_ = getSeolData(url, apikeyList[0], param); | |
158 | + // 데이터 추가 | |
159 | + for(int j = 0; j < dataTable_.getRowData().size(); j++) { | |
160 | + dataTable.getRowData().add(dataTable_.getRowData().get(j)); | |
161 | + } | |
162 | + } | |
163 | + // 페이징 갯수가 1일 경우 한번만 호출 | |
164 | + } else { | |
165 | + dataTable = getSeolData(url, apikeyList[0], param); | |
166 | + } | |
167 | + } | |
168 | + return dataTable; | |
169 | + } | |
170 | + | |
171 | + /** | |
172 | + * 마지막 문자열 치환 | |
173 | + */ | |
174 | + public String replaceLast(String string, String toReplace, String replacement) { | |
175 | + int pos = string.lastIndexOf(toReplace); | |
176 | + if (pos > -1) { | |
177 | + return string.substring(0, pos)+ replacement + string.substring(pos + toReplace.length(), string.length()); | |
178 | + } else { | |
179 | + return string; | |
180 | + } | |
181 | + } | |
182 | + | |
183 | + /** | |
184 | + * 데이터 갯수 확인 | |
185 | + */ | |
186 | + public int getSeolDataCnt(String url, String queryId) { | |
187 | + // 데이터 총 갯수 | |
188 | + int cnt = 0; | |
189 | + // 해당 queryId에 맞는 정보 호출 | |
190 | + Map<String, Object> param = (Map<String, Object>) getParam().get(queryId); | |
191 | + // 조회할 쿼리의 조건 값 | |
192 | + String requestInfo = (String) param.get("requestInfo"); | |
193 | + // 메세지 식별키 | |
194 | + String msgkey = getMsgKey(); | |
195 | + // 연계메세지 GPKI 암호화범위 <message></message> | |
196 | + // 암복호화는 표준보완API 이용(참조 : https://api.gpki.go.kr/) | |
197 | + String message = "<message>"; | |
198 | + message = message + " <body>"; | |
199 | + message = message + " <query_id>" + queryId + "</query_id>"; | |
200 | + message = message + requestInfo; | |
201 | + message = message + " </body>"; | |
202 | + message = message + " </message>"; | |
203 | + // API 요청 URL | |
204 | + url = "http://111.8.5.63:3100/stmr/websvc/std/ws?wsdl=SOWNN00213";//상주시 | |
205 | + try { | |
206 | + // 요청보낼 데이터 완성(XML) | |
207 | + String reqSoap = makeReqSoap(IFID, SRCORGCD, TGTORGCD, msgkey, message); | |
208 | + // API 요청 | |
209 | + String resSoap = sendHttpRequest(url, reqSoap, CHARSET, IFID); | |
210 | + // 문서를 읽기 위한 공장 생성(DocumentBuilder(DOM 파서)를 생성시키는 Factory 클래스) | |
211 | + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); | |
212 | + // 빌더 생성(DOM파서 객체의 클래스) | |
213 | + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); | |
214 | + // XML문서 파싱 | |
215 | + Document doc_ = dBuilder.parse(new ByteArrayInputStream(resSoap.getBytes())); | |
216 | + // DOM Tree XMl문서의 구조대로 완성 | |
217 | + doc_.getDocumentElement().normalize(); | |
218 | + // 특정 태그를 가진 모든 요소 선택(list 태그를 가진 요소 선택) | |
219 | + NodeList resultNode = doc_.getElementsByTagName("list"); | |
220 | + for(int i = 0; i < resultNode.getLength(); i++) { | |
221 | + // 자식 노드 목록 호출 | |
222 | + NodeList nList = resultNode.item(i).getChildNodes(); | |
223 | + for(int j = 0; j < nList.getLength(); j++) { | |
224 | + // 노드 값 | |
225 | + String nodeValue = nList.item(j).getTextContent(); | |
226 | + // 정보 갯수 | |
227 | + cnt = Integer.parseInt(nodeValue); | |
228 | + } | |
229 | + } | |
230 | + } catch (Exception e) { | |
231 | + // TODO: handle exception | |
232 | + e.printStackTrace(); | |
233 | + } | |
234 | + return cnt; | |
235 | + } | |
236 | + | |
237 | + /** | |
238 | + * 데이터 수집 | |
239 | + * | |
240 | + * queryId : 조회할 쿼리 ID | |
241 | + * requestInfo : 조회할 쿼리의 조건 값 -> "<dataList><data>조건값</data></dataList>" 이런형태로 들어와야한다.(조건에 따라 다중으로 들어옴) | |
242 | + * displayColumnName : 컬럼명(한글) 리스트 | |
243 | + * dataType_ : 해당 컬럼의 데이터 타입 리스트 | |
244 | + */ | |
245 | + public DataTable getSeolData(String addr, String queryId, Map<String, Object> param) { | |
246 | + // 조회할 쿼리의 조건 값 | |
247 | + String requestInfo = (String) param.get("requestInfo"); | |
248 | + System.out.println("쿼리 확인 : " + requestInfo); | |
249 | + // 컬럼정보 | |
250 | + List<ColumnData> columnDatas = (List<ColumnData>) param.get("columnDatas"); | |
251 | + // 메세지 식별키 | |
252 | + String msgkey = getMsgKey(); | |
253 | + // 연계메세지 GPKI 암호화범위 <message></message> | |
254 | + // 암복호화는 표준보완API 이용(참조 : https://api.gpki.go.kr/) | |
255 | + String message = "<message>"; | |
256 | + message = message + " <body>"; | |
257 | + message = message + " <query_id>" + queryId + "</query_id>"; | |
258 | + message = message + requestInfo; | |
259 | + message = message + " </body>"; | |
260 | + message = message + " </message>"; | |
261 | + // API 요청 URL | |
262 | + addr = "http://111.8.5.63:3100/stmr/websvc/std/ws?wsdl=SOWNN00213";//상주시 | |
263 | + try { | |
264 | + // 요청보낼 데이터 완성(XML) | |
265 | + String reqSoap = makeReqSoap(IFID, SRCORGCD, TGTORGCD, msgkey, message); | |
266 | + System.out.println("reqSoap=>\n" + reqSoap); | |
267 | + // API 요청 | |
268 | + String resSoap = sendHttpRequest(addr, reqSoap, CHARSET, IFID); | |
269 | + System.out.println("resSoap=>\n" + resSoap); | |
270 | + /** 리스트화 **/ | |
271 | + // 문서를 읽기 위한 공장 생성(DocumentBuilder(DOM 파서)를 생성시키는 Factory 클래스) | |
272 | + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); | |
273 | + // 빌더 생성(DOM파서 객체의 클래스) | |
274 | + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); | |
275 | + // XML문서 파싱 | |
276 | + Document doc_ = dBuilder.parse(new ByteArrayInputStream(resSoap.getBytes())); | |
277 | + // DOM Tree XMl문서의 구조대로 완성 | |
278 | + doc_.getDocumentElement().normalize(); | |
279 | + // 특정 태그를 가진 모든 요소 선택(list 태그를 가진 요소 선택) | |
280 | + NodeList resultNode = doc_.getElementsByTagName("list"); | |
281 | + // 데이터 값 | |
282 | + List<List<Object>> rm = new ArrayList<>(); | |
283 | + for(int i = 0; i < resultNode.getLength(); i++) { | |
284 | + // 자식 노드 목록 호출 | |
285 | + NodeList nList = resultNode.item(i).getChildNodes(); | |
286 | + // 데이터 값 | |
287 | + List<Object> nv = new ArrayList<>(); | |
288 | + for(int j = 0; j < nList.getLength(); j++) { | |
289 | + // 노드 이름 | |
290 | + String nodeName = nList.item(j).getNodeName(); | |
291 | + // 노드 값 | |
292 | + String nodeValue = nList.item(j).getTextContent(); | |
293 | + if(nodeName.equals("#text")) continue; | |
294 | + nv.add(nodeValue); | |
295 | + } | |
296 | + rm.add(nv); | |
297 | + } | |
298 | + // 컬럼 값을 담을 빈 껍데기 생성 | |
299 | + DataTable dataTable = new DataTable(); | |
300 | + dataTable.setColumnDatas(columnDatas); | |
301 | + dataTable.setRowData(rm); | |
302 | + return dataTable; | |
303 | + /* 컬럼명(영문, 한문, 타입) 배열리스트로 담기 */ | |
304 | + } catch(Exception e) { | |
305 | + e.printStackTrace(); | |
306 | + return null; | |
307 | + } | |
308 | + } | |
309 | + | |
310 | + // 메세지 식별키 생성 함수 | |
311 | + private String getMsgKey() { | |
312 | + // 현재날짜와 시간 | |
313 | + Date d = new Date(); | |
314 | + // 날짜를 원하느 포맷으로 파싱 | |
315 | + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssMS"); | |
316 | + return sdf.format(d) + String.valueOf(Math.random()).substring(2, 10); | |
317 | + } | |
318 | + | |
319 | + public synchronized String sendHttpRequest(String addr, String reqSoap, String charset, String soapAction) throws Exception { | |
320 | + OutputStream os = null; | |
321 | + BufferedWriter out = null; | |
322 | + InputStreamReader is = null; | |
323 | + BufferedReader bf = null; | |
324 | + StringBuffer response = null; | |
325 | + HttpURLConnection connection = null; | |
326 | + | |
327 | + try { | |
328 | + URL _url = new URL(addr); | |
329 | + connection = (HttpURLConnection) _url.openConnection(); | |
330 | + connection.setRequestMethod("POST"); | |
331 | + connection.setDoOutput(true); | |
332 | + connection.setDoInput(true); | |
333 | + connection.setUseCaches(false); | |
334 | + connection.setDefaultUseCaches(false); | |
335 | + connection.setRequestProperty("Content-Type", "text/xml; charset=" + charset); | |
336 | + connection.setRequestProperty("Accept", "application/soap+xml, application/dime, multipart/related, text/*"); | |
337 | + connection.setRequestProperty("SOAPAction", soapAction); | |
338 | + connection.setConnectTimeout(1000 * 60 * 10); | |
339 | + os = connection.getOutputStream(); | |
340 | + out = new BufferedWriter(new OutputStreamWriter(os, charset)); | |
341 | + out.write(reqSoap); | |
342 | + out.close(); | |
343 | + is = new InputStreamReader(connection.getInputStream(), charset); | |
344 | + bf = new BufferedReader(is); | |
345 | + response = new StringBuffer(); | |
346 | + String responsetemp; | |
347 | + while ((responsetemp = bf.readLine()) != null) { | |
348 | + response.append(responsetemp); | |
349 | + } | |
350 | + bf.close(); | |
351 | + } catch (Exception e) { | |
352 | + throw e; | |
353 | + } finally { | |
354 | + if (is != null) { | |
355 | + is.close(); | |
356 | + } | |
357 | + if (os != null) { | |
358 | + os.close(); | |
359 | + } | |
360 | + if (bf != null) { | |
361 | + bf.close(); | |
362 | + } | |
363 | + if (out != null) { | |
364 | + out.close(); | |
365 | + } | |
366 | + if (connection != null) { | |
367 | + connection = null; | |
368 | + } | |
369 | + } | |
370 | + return response.toString(); | |
371 | + } | |
372 | + | |
373 | + public String makeReqSoap(String ifid, String srcorgcd, String tgtorgcd, String msgkey, String message) throws Exception { | |
374 | + StringBuffer sb = new StringBuffer(); | |
375 | + sb.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">"); | |
376 | + sb.append(" <soapenv:Header/> "); | |
377 | + sb.append(" <soapenv:Body> "); | |
378 | + sb.append(" <DOCUMENT> "); | |
379 | + sb.append(" <IFID>" + ifid + "</IFID> "); | |
380 | + sb.append(" <SRCORGCD>" + srcorgcd + "</SRCORGCD> "); | |
381 | + sb.append(" <TGTORGCD>" + tgtorgcd + "</TGTORGCD> "); | |
382 | + sb.append(" <RESULTCODE>000</RESULTCODE> "); | |
383 | + sb.append(" <MSGKEY>" + msgkey + "</MSGKEY> "); | |
384 | + sb.append(" <DATA> "); | |
385 | + sb.append(message); | |
386 | + sb.append(" </DATA> "); | |
387 | + sb.append(" </DOCUMENT> "); | |
388 | + sb.append(" </soapenv:Body> "); | |
389 | + sb.append("</soapenv:Envelope> "); | |
390 | + return sb.toString(); | |
391 | + } | |
392 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/vo/ApiParam.java
... | ... | @@ -0,0 +1,71 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.api.vo; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.io.Serializable; | |
6 | + | |
7 | +import lombok.Getter; | |
8 | +import lombok.Setter; | |
9 | + | |
10 | +/** | |
11 | + * @author 김성원 | |
12 | + * @since 2021.11.02 | |
13 | + * | |
14 | + * Api 커넥션의 파라미터 정보를 담습니다. | |
15 | + */ | |
16 | +@Getter | |
17 | +@Setter | |
18 | +public class ApiParam implements Serializable { | |
19 | + | |
20 | + /** | |
21 | + * 시리얼 버전 | |
22 | + */ | |
23 | + private static final long serialVersionUID = 1L; | |
24 | + | |
25 | + /** | |
26 | + * 파라미터 DB저장 Key값 | |
27 | + */ | |
28 | + private String paramId; | |
29 | + | |
30 | + /** | |
31 | + * 파라미터 순서 | |
32 | + */ | |
33 | + private int index; | |
34 | + | |
35 | + /** | |
36 | + * 파라미터 Key값 | |
37 | + */ | |
38 | + private String key; | |
39 | + | |
40 | + /** | |
41 | + * 파라미터 value값 | |
42 | + */ | |
43 | + private Object value; | |
44 | + | |
45 | + /** | |
46 | + * encode 제외 변수 | |
47 | + */ | |
48 | + private boolean disableDecode; | |
49 | + | |
50 | + /** | |
51 | + * 날짜계산 변수 | |
52 | + */ | |
53 | + private boolean dateForm = false; | |
54 | + | |
55 | + | |
56 | +// /** | |
57 | +// * 날자 제어 타입(year, month, day) | |
58 | +// */ | |
59 | +// private String dateType; | |
60 | + | |
61 | + /** | |
62 | + * 날자 제어변수 | |
63 | + */ | |
64 | + private int addMonth = 0; | |
65 | + | |
66 | + | |
67 | + public static long getSerialversionuid() { | |
68 | + return serialVersionUID; | |
69 | + } | |
70 | + | |
71 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/vo/ConnectionApi.java
... | ... | @@ -0,0 +1,98 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.api.vo; | |
2 | + | |
3 | + | |
4 | +import java.io.Serializable; | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.HashMap; | |
7 | +import java.util.List; | |
8 | +import java.util.Map; | |
9 | + | |
10 | + | |
11 | +import com.takensoft.taken_bi_manager.jobs.vo.JobItm; | |
12 | +import com.takensoft.taken_bi_manager.jobs.vo.item.JobReadConItm; | |
13 | +import lombok.Getter; | |
14 | +import lombok.Setter; | |
15 | + | |
16 | +/** | |
17 | + * @author 김성원 | |
18 | + * @since 2021.11.02 | |
19 | + * | |
20 | + * Api 커넥션 정보를 담는 Class | |
21 | + */ | |
22 | +@Getter | |
23 | +@Setter | |
24 | +public class ConnectionApi extends JobReadConItm implements Serializable { | |
25 | + | |
26 | + | |
27 | + /** | |
28 | + * 연계 PAI 제목 | |
29 | + */ | |
30 | + private String title; | |
31 | + | |
32 | + /** | |
33 | + * 연계 url | |
34 | + */ | |
35 | + private String url; | |
36 | + | |
37 | + /** | |
38 | + * 연계 타입 1 = json, 2=xml | |
39 | + */ | |
40 | + private int type; | |
41 | + | |
42 | + /** | |
43 | + * 연계 타입 1 = post, 2 = get | |
44 | + */ | |
45 | + private int requestType; | |
46 | + | |
47 | + /** | |
48 | + * 연계 결과 | |
49 | + */ | |
50 | + private String result; | |
51 | + | |
52 | + /** | |
53 | + * 뎁스설정 구분자 > | |
54 | + */ | |
55 | + private String depth; | |
56 | + | |
57 | + /** | |
58 | + * 파라미터 리스트 | |
59 | + */ | |
60 | + private List<ApiParam> params = new ArrayList<ApiParam>(); | |
61 | + | |
62 | + /** | |
63 | + * 데이터(행,열)의 컬럼인 Row의 Index | |
64 | + */ | |
65 | + private int rowDataColumnIndex; | |
66 | + | |
67 | + /** | |
68 | + * 데이터(행,열)의 Row 시작 Index | |
69 | + */ | |
70 | + private int startRowIndex; | |
71 | + | |
72 | + /** | |
73 | + * 데이터(행,열)의 Cell 시작 Index | |
74 | + */ | |
75 | + private int startCellIndex; | |
76 | + | |
77 | + | |
78 | + //추가 dataset_post_id | |
79 | + private String dataset_post_id; | |
80 | + | |
81 | + public ConnectionApi() { | |
82 | + this.params = new ArrayList<ApiParam>(); | |
83 | + this.type = 1; | |
84 | + } | |
85 | + | |
86 | + | |
87 | + public Map<String, Object> paramstoMap(){ | |
88 | + Map<String, Object> result = new HashMap<String,Object>(); | |
89 | + | |
90 | + // this.params -> map | |
91 | + for(int i=0; i< this.params.size(); i++ ) { | |
92 | + result.put(this.params.get(i).getKey(), this.params.get(i).getValue()); | |
93 | + } | |
94 | + | |
95 | + return result; | |
96 | + } | |
97 | + | |
98 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/api/web/ConnectionApiRestController.java
... | ... | @@ -0,0 +1,60 @@ |
1 | + | |
2 | +package com.takensoft.taken_bi_manager.common.connection.api.web; | |
3 | + | |
4 | +import com.takensoft.taken_bi_manager.common.connection.api.service.ConnectionApiService; | |
5 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi; | |
6 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
7 | +import lombok.RequiredArgsConstructor; | |
8 | +import org.springframework.stereotype.Controller; | |
9 | +import org.springframework.web.bind.annotation.*; | |
10 | +import org.springframework.web.servlet.ModelAndView; | |
11 | + | |
12 | +@Controller | |
13 | +@RequiredArgsConstructor | |
14 | +public class ConnectionApiRestController { | |
15 | + private final ConnectionApiService connectionApiService; | |
16 | + | |
17 | + /** | |
18 | + * @author 이원호 | |
19 | + * @since 2021.11.03 | |
20 | + * | |
21 | + * OpenApi 호출 | |
22 | + */ | |
23 | + @RequestMapping(value ="/apiRequestTest.json", method = RequestMethod.POST) | |
24 | + public ModelAndView logSelectListAll(@RequestBody ConnectionApi params) throws Exception { | |
25 | + ModelAndView mav = new ModelAndView("jsonView"); | |
26 | + mav.addObject("apiResponseResult", connectionApiService.apiRequestTest(params)); | |
27 | + return mav; | |
28 | + } | |
29 | + | |
30 | + /** | |
31 | + * @author 이원호 | |
32 | + * @since 2021.11.05 | |
33 | + * | |
34 | + * Api dataTable 호출 | |
35 | + */ | |
36 | + @RequestMapping(value ="/getApiDataTable.json", method = RequestMethod.POST) | |
37 | + public ModelAndView getApiDataTable(@RequestBody ConnectionApi connectionApi) throws Exception{ | |
38 | + ModelAndView mav = new ModelAndView("jsonView"); | |
39 | + DataTable dataTable = connectionApiService.apiRequest(connectionApi); | |
40 | + mav.addObject("dataTableResult", dataTable); | |
41 | + | |
42 | + return mav; | |
43 | + } | |
44 | + | |
45 | + /** | |
46 | + * @author 이원호 | |
47 | + * @since 2021.11.10 | |
48 | + * | |
49 | + * API 연계정보 등록 | |
50 | + */ | |
51 | + @RequestMapping(value ="/apiConnectionInfoInsert.json", method = RequestMethod.POST) | |
52 | + public ModelAndView apiConnectionInfoInsert( @RequestBody ConnectionApi connectionApi ) throws Exception{ | |
53 | + ModelAndView mav = new ModelAndView("jsonView"); | |
54 | + connectionApiService.apiConnectionInfoInsert(connectionApi); | |
55 | + connectionApiService.apiParameterInfoInsert(connectionApi); | |
56 | + mav.addObject("dataTableResult", "success"); | |
57 | + | |
58 | + return mav; | |
59 | + } | |
60 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/DatabaseDAO.java
... | ... | @@ -0,0 +1,239 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.dao; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.util.LinkedHashMap; | |
6 | +import java.util.List; | |
7 | +import java.util.Map; | |
8 | + | |
9 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
10 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo; | |
11 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
12 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
13 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
14 | + | |
15 | + | |
16 | +/** | |
17 | + * @author 김성원 | |
18 | + * @since 2024.01.09 | |
19 | + * | |
20 | + * 데이터베이스 접속 모듈에 관련된 SQL문에 접근하는 DAO 추상 Class입니다. | |
21 | + */ | |
22 | +public abstract class DatabaseDAO { | |
23 | + | |
24 | + /** | |
25 | + * @author 김성원 | |
26 | + * @since 2024.01.09 | |
27 | + * | |
28 | + * SqlSessionTemplate 생성 메서드 입니다. | |
29 | + */ | |
30 | + public abstract void createConnector (ConnectionDB db) throws Exception; | |
31 | + | |
32 | + /** | |
33 | + * @author 김성원 | |
34 | + * @since 2024.01.09 | |
35 | + * | |
36 | + * 접속한 데이터베이스의 테이블 목록 조회 SQL에 접근하는 메소드 입니다. | |
37 | + */ | |
38 | + public abstract List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception; | |
39 | + | |
40 | + /** | |
41 | + * @author 김성원 | |
42 | + * @since 2024.01.09 | |
43 | + * | |
44 | + * 커넥션된 데이터베이스의 테이블의 컬럼 정보 조회 (DB 기준 데이터 타입, 데이터 크기 등) | |
45 | + */ | |
46 | + public abstract List<ColumnData> getDBConnectionTableColumnList (Dataset dataset) throws Exception; | |
47 | + | |
48 | + /** | |
49 | + * @author 김성원 | |
50 | + * @since 2024.01.09 | |
51 | + * | |
52 | + * 특정 테이블의 데이터 목록 조회 SQL에 접근하는 메소드 입니다. | |
53 | + */ | |
54 | + public abstract List<LinkedHashMap<String, Object>> getDBConnectionTableDataList (DataTable datatable) throws Exception; | |
55 | + | |
56 | + /** | |
57 | + * @author 김성원 | |
58 | + * @since 2024.01.09 | |
59 | + * | |
60 | + * 특정 테이블의 데이터 총 개수 조회 SQL에 접근하는 메소드 입니다. | |
61 | + */ | |
62 | + public abstract int getDBConnectionTableDataTotalRows (DataTable datatable) throws Exception; | |
63 | + | |
64 | + | |
65 | + /** | |
66 | + * @author 김성원 | |
67 | + * @since 2024.01.09 | |
68 | + * | |
69 | + * 특정 테이블의 데이터 목록 조회 SQL에 접근하는 메소드 입니다. | |
70 | + */ | |
71 | + public abstract List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList (DataTable datatable) throws Exception; | |
72 | + | |
73 | + | |
74 | + /** | |
75 | + * @author 김성원 | |
76 | + * @since 2024.01.09 | |
77 | + * | |
78 | + * 조회 없는 실행형 쿼리 | |
79 | + */ | |
80 | + public abstract int executeCustomQuery (DataTable datatable) throws Exception; | |
81 | + | |
82 | + | |
83 | + /** | |
84 | + * @author 김성원 | |
85 | + * @since 2024.01.097 | |
86 | + * | |
87 | + * 특정 테이블의 데이터 총 개수 조회 SQL에 접근하는 메소드 입니다. | |
88 | + */ | |
89 | + public abstract int getDBConnectionCustomQueryDataTotalRows (DataTable datatable) throws Exception; | |
90 | + | |
91 | + /** | |
92 | + * @author 김성원 | |
93 | + * @since 2024.01.09 | |
94 | + * | |
95 | + * DB연계 데이터 목록 조회 (초기 DB화 때에 등록한 컬럼만 가지고 옴) | |
96 | + */ | |
97 | + public abstract List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList (DataTable datatable) throws Exception; | |
98 | + | |
99 | + /** | |
100 | + * @author 김성원 | |
101 | + * @since 2024.01.09 | |
102 | + * | |
103 | + * DB연계 데이터 목록 총 갯수 조회 | |
104 | + */ | |
105 | + public abstract int getDBCollectionQueryDataTotalRows (DataTable datatable) throws Exception; | |
106 | + | |
107 | + | |
108 | + /** | |
109 | + * @author 김성원 | |
110 | + * @since 2024.01.09 | |
111 | + * | |
112 | + * 커트텀 쿼리 지정된 PK의 중복 데이터 수 (지정된 PK로 Table 생성이 가능한지 알아보기 위함) | |
113 | + */ | |
114 | + public abstract int getCustomQueryPrimaryOverlapCount (DataTable datatable) throws Exception; | |
115 | + | |
116 | + /** | |
117 | + * @author 김성원 | |
118 | + * @since 2024.01.09 | |
119 | + * | |
120 | + * DataSource Close | |
121 | + */ | |
122 | + public abstract void dbConnectionClose() throws Exception; | |
123 | + | |
124 | + /** | |
125 | + * @author 김성원 | |
126 | + * @since 2024.01.09 | |
127 | + * | |
128 | + * 쿼리 실행후, 실행한 쿼리문 조회 | |
129 | + */ | |
130 | + public abstract String getQuery (String id, Object parameter) throws Exception; | |
131 | + | |
132 | + /** | |
133 | + * @author 김성원 | |
134 | + * @since 2024.01.09 | |
135 | + * | |
136 | + * 커넥션된 데이터베이스의 실제 테이블 생성(pk 존재유) | |
137 | + */ | |
138 | + public abstract int datasetTableCreate(DataTable datatable) throws Exception; | |
139 | + | |
140 | + /** | |
141 | + * @author 김성원 | |
142 | + * @since 2024.01.09 | |
143 | + * | |
144 | + * 커넥션된 데이터베이스의 실제 테이블 생성(pk 존재무) | |
145 | + */ | |
146 | + public abstract int datasetDefaultTableCreate(DataTable datatable) throws Exception; | |
147 | + | |
148 | + /** | |
149 | + * @author 김성원 | |
150 | + * @since 2022.01.17 | |
151 | + * | |
152 | + * 커넥션된 데이터 베이스 데이터 업데이트(pk 존재무) | |
153 | + */ | |
154 | + public abstract void datasetDataUpdate(DataTable datatable) throws Exception; | |
155 | + | |
156 | + /** | |
157 | + * @author 김성원 | |
158 | + * @since 2022.01.17 | |
159 | + * | |
160 | + * 데이터 셋의 ROW 삭제 | |
161 | + */ | |
162 | + public abstract void datasetDataDelete(DataTable datatable) throws Exception; | |
163 | + | |
164 | + | |
165 | + /** | |
166 | + * @author 김성원 | |
167 | + * @since 2022.01.17 | |
168 | + * | |
169 | + * 커넥션된 데이터 베이스 중복체크 (pk 존재무) | |
170 | + */ | |
171 | + public abstract int duplicateCheckTableName(Map info) throws Exception; | |
172 | + | |
173 | + | |
174 | + /** | |
175 | + * @author 김성원 | |
176 | + * @since 2022.01.17 | |
177 | + * | |
178 | + * 데이터 셋의 컬럼 정보 목록 조회 SQL에 접근하는 메소드 입니다.(페이징) | |
179 | + */ | |
180 | + public abstract List<LinkedHashMap<String, Object>> getRowData (DataTable dataTable) throws Exception; | |
181 | + | |
182 | + /** | |
183 | + * @author 김성원 | |
184 | + * @since 2022.01.17 | |
185 | + * | |
186 | + * 데이터 셋의 컬럼 정보 목록 조회 SQL에 접근하는 메소드 입니다.(x) | |
187 | + */ | |
188 | + public abstract List<LinkedHashMap<String, Object>> getRowDataAll (DataTable dataTable) throws Exception; | |
189 | + | |
190 | + /** | |
191 | + * @author 최정우 | |
192 | + * @since 2019.12.09 | |
193 | + * | |
194 | + * 데이터 셋의 컬럼 정보 목록 총 갯수 조회 메소드 입니다. | |
195 | + */ | |
196 | + public abstract int getRowDataTotalRows (DataTable dataTable) throws Exception; | |
197 | + | |
198 | + /** | |
199 | + * @author 김성원 | |
200 | + * @since 2022.1.12 | |
201 | + * | |
202 | + * 데이터 셋의 비우기 (데이터 셋 내용삭제) | |
203 | + */ | |
204 | + public abstract int emptyDataset (DataTable dataTable) throws Exception; | |
205 | + | |
206 | + /** | |
207 | + * @author 김성원 | |
208 | + * @since 2022.1.20 | |
209 | + * | |
210 | + * 실제 생성된 컬럼 변경 | |
211 | + */ | |
212 | + public abstract int tableColumnChange (TableBasicInfo tableBasicInfo) throws Exception; | |
213 | + | |
214 | + /** | |
215 | + * @author 김성원 | |
216 | + * @since 2022.1.20 | |
217 | + * | |
218 | + * 실제 생성된 테이블 PK처리 | |
219 | + */ | |
220 | + public abstract int changePrimaryKey (TableBasicInfo tableBasicInfo) throws Exception; | |
221 | + | |
222 | + /** | |
223 | + * @author 김성원 | |
224 | + * @since 2022.1.20 | |
225 | + * | |
226 | + * AI PK 생성 | |
227 | + */ | |
228 | + public abstract int createAutoIncrement (TableBasicInfo tableBasicInfo) throws Exception; | |
229 | + | |
230 | + | |
231 | + /** | |
232 | + * @author 김성원 | |
233 | + * @since 2022.09.30 | |
234 | + * | |
235 | + * 테이블 명 변경 | |
236 | + * | |
237 | + */ | |
238 | + public abstract void updateTableMetaInfo(DataTable dataTable) throws Exception; | |
239 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/MariadbDAO.java
... | ... | @@ -0,0 +1,291 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.dao; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.HashMap; | |
7 | +import java.util.LinkedHashMap; | |
8 | +import java.util.List; | |
9 | +import java.util.Map; | |
10 | + | |
11 | +import org.apache.ibatis.mapping.ParameterMapping; | |
12 | +import org.mybatis.spring.SqlSessionTemplate; | |
13 | +import org.springframework.stereotype.Repository; | |
14 | + | |
15 | +import com.fasterxml.jackson.core.type.TypeReference; | |
16 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
17 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig; | |
18 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
19 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo; | |
20 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
21 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
22 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
23 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
24 | + | |
25 | + | |
26 | +/** | |
27 | + * @author 김성원 | |
28 | + * @since 2024.01.09 | |
29 | + * | |
30 | + * Mariadb 접속 모듈에 관련된 SQL문에 접근하는 DAO Class입니다. | |
31 | + */ | |
32 | +@Repository | |
33 | +public class MariadbDAO extends DatabaseDAO { | |
34 | + | |
35 | + public MariadbDAO () {} | |
36 | + | |
37 | + public MariadbDAO (ConnectionDB db) throws Exception { | |
38 | + this.createConnector(db); | |
39 | + } | |
40 | + | |
41 | + private DBConnectionConfig dbUtil = null; | |
42 | + | |
43 | + public DBConnectionConfig getDbUtil() { | |
44 | + return dbUtil; | |
45 | + } | |
46 | + public void setDbUtil(DBConnectionConfig dbUtil) { | |
47 | + this.dbUtil = dbUtil; | |
48 | + } | |
49 | + | |
50 | + /** | |
51 | + * @author 김성원 | |
52 | + * @since 2024.01.09 | |
53 | + * | |
54 | + * SqlSessionTemplate 생성 메서드 입니다. | |
55 | + */ | |
56 | + @Override | |
57 | + public void createConnector (ConnectionDB db) throws Exception { | |
58 | + dbUtil = new DBConnectionConfig(); | |
59 | + dbUtil.mybatisSqlTemplateCreate(db); | |
60 | + } | |
61 | + | |
62 | + /** | |
63 | + * @author 김성원 | |
64 | + * @since 2024.01.09 | |
65 | + * | |
66 | + * 접속한 데이터베이스의 테이블 목록 조회 SQL에 접근하는 메소드 입니다. | |
67 | + */ | |
68 | + @Override | |
69 | + public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception { | |
70 | + try { | |
71 | + return dbUtil.getTemplate().selectList("MariadbDAO.getDBConnectionTableList", db); | |
72 | + } catch (Exception e) { | |
73 | + return new ArrayList<Dataset>(); | |
74 | + } | |
75 | + } | |
76 | + | |
77 | + /** | |
78 | + * @author 김성원 | |
79 | + * @since 2024.01.09 | |
80 | + * | |
81 | + * 커넥션된 데이터베이스의 테이블의 컬럼 정보 조회 (DB 기준 데이터 타입, 데이터 크기 등) | |
82 | + */ | |
83 | + @Override | |
84 | + public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception { | |
85 | + return dbUtil.getTemplate().selectList("MariadbDAO.getDBConnectionTableColumnList", dataset); | |
86 | + } | |
87 | + | |
88 | + /** | |
89 | + * @author 김성원 | |
90 | + * @since 2024.01.09 | |
91 | + * | |
92 | + * 특정 테이블의 데이터 목록 조회 SQL에 접근하는 메소드 입니다. | |
93 | + */ | |
94 | + @Override | |
95 | + public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList (DataTable datatable) throws Exception { | |
96 | + return dbUtil.getTemplate().selectList("MariadbDAO.getDBConnectionTableDataList", datatable); | |
97 | + } | |
98 | + | |
99 | + /** | |
100 | + * @author 김성원 | |
101 | + * @since 2024.01.09 | |
102 | + * | |
103 | + * 특정 테이블의 데이터 총 개수 조회 SQL에 접근하는 메소드 입니다. | |
104 | + */ | |
105 | + @Override | |
106 | + public int getDBConnectionTableDataTotalRows (DataTable datatable) throws Exception { | |
107 | + return dbUtil.getTemplate().selectOne("MariadbDAO.getDBConnectionTableDataTotalRows", datatable); | |
108 | + } | |
109 | + | |
110 | + /** | |
111 | + * @author 김성원 | |
112 | + * @since 2024.01.09 | |
113 | + * | |
114 | + * 커스텀 테이블 데이터 조회 (페이징사용 유무에 따라 페이징 처리) SQL에 접근하는 메소드 입니다. | |
115 | + */ | |
116 | + @Override | |
117 | + public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList (DataTable datatable) throws Exception { | |
118 | + return dbUtil.getTemplate().selectList("MariadbDAO.getDBConnectionCustomQueryDataList", datatable); | |
119 | + } | |
120 | + | |
121 | + /** | |
122 | + * @author 김성원 | |
123 | + * @since 2024.01.09 | |
124 | + * | |
125 | + * 커스텀 테이블 데이터 목록 총 갯수 조회 SQL에 접근하는 메소드 입니다. | |
126 | + */ | |
127 | + @Override | |
128 | + public int getDBConnectionCustomQueryDataTotalRows (DataTable datatable) throws Exception { | |
129 | + return dbUtil.getTemplate().selectOne("MariadbDAO.getDBConnectionCustomQueryDataTotalRows", datatable); | |
130 | + } | |
131 | + | |
132 | + /** | |
133 | + * @author 김성원 | |
134 | + * @since 2024.01.09 | |
135 | + * | |
136 | + * DB연계 데이터 목록 조회 (초기 DB화 때에 등록한 컬럼만 가지고 옴) | |
137 | + */ | |
138 | + @Override | |
139 | + public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList (DataTable datatable) throws Exception { | |
140 | + return dbUtil.getTemplate().selectList("MariadbDAO.getDBCollectionQueryDataList", datatable); | |
141 | + } | |
142 | + | |
143 | + /** | |
144 | + * @author 김성원 | |
145 | + * @since 2024.01.09 | |
146 | + * | |
147 | + * DB연계 데이터 목록 총 갯수 조회 | |
148 | + */ | |
149 | + @Override | |
150 | + public int getDBCollectionQueryDataTotalRows (DataTable datatable) throws Exception { | |
151 | + return dbUtil.getTemplate().selectOne("MariadbDAO.getDBCollectionQueryDataTotalRows", datatable); | |
152 | + } | |
153 | + | |
154 | + /** | |
155 | + * @author 김성원 | |
156 | + * @since 2024.01.09 | |
157 | + * | |
158 | + * 커트텀 쿼리 지정된 PK의 중복 데이터 수 (지정된 PK로 Table 생성이 가능한지 알아보기 위함) | |
159 | + */ | |
160 | + @Override | |
161 | + public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception { | |
162 | + return dbUtil.getTemplate().selectOne("MariadbDAO.getCustomQueryPrimaryOverlapCount", datatable); | |
163 | + } | |
164 | + | |
165 | + /** | |
166 | + * @author 김성원 | |
167 | + * @since 2024.01.09 | |
168 | + * | |
169 | + * SqlSessionTemplate Close | |
170 | + */ | |
171 | + @Override | |
172 | + public void dbConnectionClose() throws Exception { | |
173 | + dbUtil.close(); | |
174 | + } | |
175 | + | |
176 | + /** | |
177 | + * @author 김성원 | |
178 | + * @since 2024.01.09 | |
179 | + * | |
180 | + * 쿼리 실행후, 실행한 쿼리문 조회 | |
181 | + */ | |
182 | + @Override | |
183 | + public String getQuery (String id, Object parameter) throws Exception { | |
184 | + SqlSessionTemplate template = dbUtil.getTemplate(); | |
185 | + | |
186 | + id = "OracleDAO." + id; | |
187 | + | |
188 | + String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql(); | |
189 | + List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings(); | |
190 | + | |
191 | + ObjectMapper mapper = new ObjectMapper(); | |
192 | + String json = mapper.writeValueAsString(parameter); | |
193 | + HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){}); | |
194 | + for (ParameterMapping par : paramMap) { | |
195 | + String param = StringUtil.toString(params.get(par.getProperty())); | |
196 | + if(parameter == null) | |
197 | + sql = sql.replaceFirst("\\?", "NULL"); | |
198 | + else | |
199 | + sql = sql.replaceFirst("\\?", "'" + param + "'"); | |
200 | + } | |
201 | + | |
202 | + return sql; | |
203 | + } | |
204 | + | |
205 | + @Override | |
206 | + public int datasetTableCreate(DataTable datatable) throws Exception { | |
207 | + // TODO Auto-generated method stub | |
208 | + return dbUtil.getTemplate().update("MariadbDAO.datasetTableCreate", datatable); | |
209 | + } | |
210 | + | |
211 | + @Override | |
212 | + public int datasetDefaultTableCreate(DataTable datatable) throws Exception { | |
213 | + // TODO Auto-generated method stub | |
214 | + return dbUtil.getTemplate().update("MariadbDAO.datasetDefaultTableCreate", datatable); | |
215 | + } | |
216 | + | |
217 | + @Override | |
218 | + public void datasetDataUpdate(DataTable datatable) throws Exception { | |
219 | + // TODO Auto-generated method stub | |
220 | + dbUtil.getTemplate().update("MariadbDAO.datasetDataUpdate", datatable); | |
221 | + } | |
222 | + | |
223 | + @Override | |
224 | + public int duplicateCheckTableName(Map info) throws Exception { | |
225 | + // TODO Auto-generated method stub | |
226 | + return dbUtil.getTemplate().selectOne("MariadbDAO.duplicateCheckTableName", info); | |
227 | + } | |
228 | + | |
229 | + @Override | |
230 | + public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception { | |
231 | + // TODO Auto-generated method stub | |
232 | + return dbUtil.getTemplate().selectList("MariadbDAO.getRowData", dataTable); | |
233 | + } | |
234 | + | |
235 | + @Override | |
236 | + public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception { | |
237 | + return dbUtil.getTemplate().selectList("MariadbDAO.getRowDataAll", dataTable); | |
238 | + } | |
239 | + | |
240 | + @Override | |
241 | + public int getRowDataTotalRows(DataTable dataTable) throws Exception { | |
242 | + // TODO Auto-generated method stub | |
243 | + return dbUtil.getTemplate().selectOne("MariadbDAO.getRowDataTotalRows", dataTable); | |
244 | + } | |
245 | + | |
246 | + @Override | |
247 | + public int emptyDataset(DataTable dataTable) throws Exception { | |
248 | + // TODO Auto-generated method stub | |
249 | + return dbUtil.getTemplate().delete("MariadbDAO.emptyDataset", dataTable); | |
250 | + } | |
251 | + | |
252 | + @Override | |
253 | + public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception { | |
254 | + // TODO Auto-generated method stub | |
255 | + return dbUtil.getTemplate().update("MariadbDAO.tableColumnChange", tableBasicInfo); | |
256 | + } | |
257 | + | |
258 | + | |
259 | + @Override | |
260 | + public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception { | |
261 | + // TODO Auto-generated method stub | |
262 | + return dbUtil.getTemplate().update("MariadbDAO.changePromaryKey", tableBasicInfo); | |
263 | + } | |
264 | + | |
265 | + | |
266 | + @Override | |
267 | + public void datasetDataDelete(DataTable datatable) throws Exception { | |
268 | + // TODO Auto-generated method stub | |
269 | + dbUtil.getTemplate().delete("MariadbDAO.datasetDataDelete", datatable); | |
270 | + } | |
271 | + | |
272 | + @Override | |
273 | + public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception { | |
274 | + | |
275 | + return dbUtil.getTemplate().update("MariadbDAO.createAutoIncrement", tableBasicInfo); | |
276 | + | |
277 | + } | |
278 | + | |
279 | + @Override | |
280 | + public int executeCustomQuery(DataTable datatable) throws Exception { | |
281 | + | |
282 | + return dbUtil.getTemplate().update("MariadbDAO.executeCustomQuery", datatable); | |
283 | + } | |
284 | + | |
285 | + | |
286 | + @Override | |
287 | + public void updateTableMetaInfo(DataTable dataTable) throws Exception { | |
288 | + // TODO Auto-generated method stub | |
289 | + | |
290 | + } | |
291 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/MssqlDAO.java
... | ... | @@ -0,0 +1,195 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.dao; | |
2 | + | |
3 | +import com.fasterxml.jackson.core.type.TypeReference; | |
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
5 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig; | |
6 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
7 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo; | |
8 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
9 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
10 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
11 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
12 | +import org.apache.ibatis.mapping.ParameterMapping; | |
13 | +import org.mybatis.spring.SqlSessionTemplate; | |
14 | +import org.springframework.stereotype.Repository; | |
15 | + | |
16 | +import java.util.*; | |
17 | + | |
18 | +/** | |
19 | + * @author 박민혁 | |
20 | + * @since 2024.04.04 | |
21 | + * | |
22 | + * MssqlDAO 접속 모듈에 관련된 SQL문에 접근하는 DAO Class입니다. | |
23 | + */ | |
24 | +@Repository | |
25 | +public class MssqlDAO extends DatabaseDAO { | |
26 | + | |
27 | + public MssqlDAO () {} | |
28 | + | |
29 | + public MssqlDAO (ConnectionDB db) throws Exception{ | |
30 | + this.createConnector(db); | |
31 | + } | |
32 | + | |
33 | + private DBConnectionConfig dbUtil = null; | |
34 | + | |
35 | + public DBConnectionConfig getDbUtil() { | |
36 | + return dbUtil; | |
37 | + } | |
38 | + public void setDbUtil(DBConnectionConfig dbUtil) { | |
39 | + this.dbUtil = dbUtil; | |
40 | + } | |
41 | + | |
42 | + @Override | |
43 | + public void createConnector (ConnectionDB db) throws Exception { | |
44 | + dbUtil = new DBConnectionConfig(); | |
45 | + dbUtil.mybatisSqlTemplateCreate(db); | |
46 | + } | |
47 | + | |
48 | + @Override | |
49 | + public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception { | |
50 | + try { | |
51 | + return dbUtil.getTemplate().selectList("MssqlDAO.getDBConnectionTableList", db); | |
52 | + } catch (Exception e) { | |
53 | + return new ArrayList<Dataset>(); | |
54 | + } | |
55 | + } | |
56 | + | |
57 | + @Override | |
58 | + public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception { | |
59 | + return dbUtil.getTemplate().selectList("MssqlDAO.getDBConnectionTableColumnList", dataset); | |
60 | + } | |
61 | + | |
62 | + @Override | |
63 | + public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList(DataTable datatable) throws Exception { | |
64 | + return dbUtil.getTemplate().selectList("MssqlDAO.getDBConnectionTableDataList", datatable); | |
65 | + } | |
66 | + | |
67 | + @Override | |
68 | + public int getDBConnectionTableDataTotalRows(DataTable datatable) throws Exception { | |
69 | + return dbUtil.getTemplate().selectOne("MssqlDAO.getDBConnectionTableDataTotalRows", datatable); | |
70 | + } | |
71 | + | |
72 | + @Override | |
73 | + public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList(DataTable datatable) throws Exception { | |
74 | + return dbUtil.getTemplate().selectList("MssqlDAO.getDBConnectionCustomQueryDataList", datatable); | |
75 | + } | |
76 | + | |
77 | + @Override | |
78 | + public int executeCustomQuery(DataTable datatable) throws Exception { | |
79 | + return dbUtil.getTemplate().update("MssqlDAO.executeCustomQuery", datatable); | |
80 | + } | |
81 | + | |
82 | + @Override | |
83 | + public int getDBConnectionCustomQueryDataTotalRows(DataTable datatable) throws Exception { | |
84 | + return dbUtil.getTemplate().selectOne("MssqlDAO.getDBConnectionCustomQueryDataTotalRows", datatable); | |
85 | + } | |
86 | + | |
87 | + @Override | |
88 | + public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList(DataTable datatable) throws Exception { | |
89 | + return dbUtil.getTemplate().selectList("MssqlDAO.getDBCollectionQueryDataList", datatable); | |
90 | + } | |
91 | + | |
92 | + @Override | |
93 | + public int getDBCollectionQueryDataTotalRows(DataTable datatable) throws Exception { | |
94 | + return dbUtil.getTemplate().selectOne("MssqlDAO.getDBCollectionQueryDataTotalRows", datatable); | |
95 | + } | |
96 | + | |
97 | + @Override | |
98 | + public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception { | |
99 | + return dbUtil.getTemplate().selectOne("MssqlDAO.getCustomQueryPrimaryOverlapCount", datatable); | |
100 | + } | |
101 | + | |
102 | + @Override | |
103 | + public void dbConnectionClose() throws Exception { | |
104 | + dbUtil.close(); | |
105 | + } | |
106 | + | |
107 | + @Override | |
108 | + public String getQuery(String id, Object parameter) throws Exception { | |
109 | + SqlSessionTemplate template = dbUtil.getTemplate(); | |
110 | + | |
111 | + id = "MssqlDAO." + id; | |
112 | + | |
113 | + String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql(); | |
114 | + List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings(); | |
115 | + | |
116 | + ObjectMapper mapper = new ObjectMapper(); | |
117 | + String json = mapper.writeValueAsString(parameter); | |
118 | + HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){}); | |
119 | + for (ParameterMapping par : paramMap) { | |
120 | + String param = StringUtil.toString(params.get(par.getProperty())); | |
121 | + if(parameter == null) | |
122 | + sql = sql.replaceFirst("\\?", "NULL"); | |
123 | + else | |
124 | + sql = sql.replaceFirst("\\?", "'" + param + "'"); | |
125 | + } | |
126 | + | |
127 | + return sql; | |
128 | + } | |
129 | + | |
130 | + @Override | |
131 | + public int datasetTableCreate(DataTable datatable) throws Exception { | |
132 | + return dbUtil.getTemplate().update("MssqlDAO.datasetTableCreate", datatable); | |
133 | + } | |
134 | + | |
135 | + @Override | |
136 | + public int datasetDefaultTableCreate(DataTable datatable) throws Exception { | |
137 | + return dbUtil.getTemplate().update("MssqlDAO.datasetDefaultTableCreate", datatable); | |
138 | + } | |
139 | + | |
140 | + @Override | |
141 | + public void datasetDataUpdate(DataTable datatable) throws Exception { | |
142 | + dbUtil.getTemplate().update("MssqlDAO.datasetDataUpdate", datatable); | |
143 | + } | |
144 | + | |
145 | + @Override | |
146 | + public void datasetDataDelete(DataTable datatable) throws Exception { | |
147 | + dbUtil.getTemplate().delete("MssqlDAO.datasetDataDelete", datatable); | |
148 | + } | |
149 | + | |
150 | + @Override | |
151 | + public int duplicateCheckTableName(Map info) throws Exception { | |
152 | + return dbUtil.getTemplate().selectOne("MssqlDAO.duplicateCheckTableName", info); | |
153 | + } | |
154 | + | |
155 | + @Override | |
156 | + public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception { | |
157 | + return dbUtil.getTemplate().selectList("MssqlDAO.getRowData", dataTable); | |
158 | + } | |
159 | + | |
160 | + @Override | |
161 | + public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception { | |
162 | + return dbUtil.getTemplate().selectList("MssqlDAO.getRowDataAll", dataTable); | |
163 | + } | |
164 | + | |
165 | + @Override | |
166 | + public int getRowDataTotalRows(DataTable dataTable) throws Exception { | |
167 | + return dbUtil.getTemplate().selectOne("MssqlDAO.getRowDataTotalRows", dataTable); | |
168 | + } | |
169 | + | |
170 | + @Override | |
171 | + public int emptyDataset(DataTable dataTable) throws Exception { | |
172 | + return dbUtil.getTemplate().delete("MssqlDAO.emptyDataset", dataTable); | |
173 | + } | |
174 | + | |
175 | + @Override | |
176 | + public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception { | |
177 | + return dbUtil.getTemplate().update("MssqlDAO.tableColumnChange", tableBasicInfo); | |
178 | + } | |
179 | + | |
180 | + @Override | |
181 | + public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception { | |
182 | + return dbUtil.getTemplate().update("MssqlDAO.changePromaryKey", tableBasicInfo); | |
183 | + } | |
184 | + | |
185 | + @Override | |
186 | + public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception { | |
187 | + return dbUtil.getTemplate().update("MssqlDAO.createAutoIncrement", tableBasicInfo); | |
188 | + } | |
189 | + | |
190 | + @Override | |
191 | + public void updateTableMetaInfo(DataTable dataTable) throws Exception { | |
192 | + dbUtil.getTemplate().update("MssqlDAO.updateTableMetaInfo", dataTable); | |
193 | + } | |
194 | + | |
195 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/MysqlDAO.java
... | ... | @@ -0,0 +1,193 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.dao; | |
2 | + | |
3 | +import com.fasterxml.jackson.core.type.TypeReference; | |
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
5 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig; | |
6 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
7 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo; | |
8 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
9 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
10 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
11 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
12 | +import org.apache.ibatis.mapping.ParameterMapping; | |
13 | +import org.mybatis.spring.SqlSessionTemplate; | |
14 | +import org.springframework.stereotype.Repository; | |
15 | + | |
16 | +import java.util.*; | |
17 | + | |
18 | +/** | |
19 | + * @author 박민혁 | |
20 | + * @since 2024.03.28 | |
21 | + * | |
22 | + * Mysql 접속 모듈에 관련된 SQL문에 접근하는 DAO Class입니다. | |
23 | + */ | |
24 | +@Repository | |
25 | +public class MysqlDAO extends DatabaseDAO { | |
26 | + | |
27 | + public MysqlDAO (){} | |
28 | + | |
29 | + public MysqlDAO (ConnectionDB db) throws Exception{ | |
30 | + this.createConnector(db); | |
31 | + } | |
32 | + private DBConnectionConfig dbUtil = null; | |
33 | + | |
34 | + public DBConnectionConfig getDbUtil() { | |
35 | + return dbUtil; | |
36 | + } | |
37 | + public void setDbUtil(DBConnectionConfig dbUtil) { | |
38 | + this.dbUtil = dbUtil; | |
39 | + } | |
40 | + | |
41 | + @Override | |
42 | + public void createConnector (ConnectionDB db) throws Exception { | |
43 | + dbUtil = new DBConnectionConfig(); | |
44 | + dbUtil.mybatisSqlTemplateCreate(db); | |
45 | + } | |
46 | + | |
47 | + @Override | |
48 | + public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception { | |
49 | + try { | |
50 | + return dbUtil.getTemplate().selectList("MysqlDAO.getDBConnectionTableList", db); | |
51 | + } catch (Exception e) { | |
52 | + return new ArrayList<Dataset>(); | |
53 | + } | |
54 | + } | |
55 | + | |
56 | + @Override | |
57 | + public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception { | |
58 | + return dbUtil.getTemplate().selectList("MysqlDAO.getDBConnectionTableColumnList", dataset); | |
59 | + } | |
60 | + | |
61 | + @Override | |
62 | + public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList(DataTable datatable) throws Exception { | |
63 | + return dbUtil.getTemplate().selectList("MysqlDAO.getDBConnectionTableDataList", datatable); | |
64 | + } | |
65 | + | |
66 | + @Override | |
67 | + public int getDBConnectionTableDataTotalRows(DataTable datatable) throws Exception { | |
68 | + return dbUtil.getTemplate().selectOne("MysqlDAO.getDBConnectionTableDataTotalRows", datatable); | |
69 | + } | |
70 | + | |
71 | + @Override | |
72 | + public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList(DataTable datatable) throws Exception { | |
73 | + return dbUtil.getTemplate().selectList("MysqlDAO.getDBConnectionCustomQueryDataList", datatable); | |
74 | + } | |
75 | + | |
76 | + @Override | |
77 | + public int executeCustomQuery(DataTable datatable) throws Exception { | |
78 | + return dbUtil.getTemplate().update("MysqlDAO.executeCustomQuery", datatable); | |
79 | + } | |
80 | + | |
81 | + @Override | |
82 | + public int getDBConnectionCustomQueryDataTotalRows(DataTable datatable) throws Exception { | |
83 | + return dbUtil.getTemplate().selectOne("MysqlDAO.getDBConnectionCustomQueryDataTotalRows", datatable); | |
84 | + } | |
85 | + | |
86 | + @Override | |
87 | + public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList(DataTable datatable) throws Exception { | |
88 | + return dbUtil.getTemplate().selectList("MysqlDAO.getDBCollectionQueryDataList", datatable); | |
89 | + } | |
90 | + | |
91 | + @Override | |
92 | + public int getDBCollectionQueryDataTotalRows(DataTable datatable) throws Exception { | |
93 | + return dbUtil.getTemplate().selectOne("MysqlDAO.getDBCollectionQueryDataTotalRows", datatable); | |
94 | + } | |
95 | + | |
96 | + @Override | |
97 | + public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception { | |
98 | + return dbUtil.getTemplate().selectOne("MysqlDAO.getCustomQueryPrimaryOverlapCount", datatable); | |
99 | + } | |
100 | + | |
101 | + @Override | |
102 | + public void dbConnectionClose() throws Exception { | |
103 | + dbUtil.close(); | |
104 | + } | |
105 | + | |
106 | + @Override | |
107 | + public String getQuery(String id, Object parameter) throws Exception { | |
108 | + SqlSessionTemplate template = dbUtil.getTemplate(); | |
109 | + | |
110 | + id = "MysqlDAO." + id; | |
111 | + | |
112 | + String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql(); | |
113 | + List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings(); | |
114 | + | |
115 | + ObjectMapper mapper = new ObjectMapper(); | |
116 | + String json = mapper.writeValueAsString(parameter); | |
117 | + HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){}); | |
118 | + for (ParameterMapping par : paramMap) { | |
119 | + String param = StringUtil.toString(params.get(par.getProperty())); | |
120 | + if(parameter == null) | |
121 | + sql = sql.replaceFirst("\\?", "NULL"); | |
122 | + else | |
123 | + sql = sql.replaceFirst("\\?", "'" + param + "'"); | |
124 | + } | |
125 | + | |
126 | + return sql; | |
127 | + } | |
128 | + | |
129 | + @Override | |
130 | + public int datasetTableCreate(DataTable datatable) throws Exception { | |
131 | + return dbUtil.getTemplate().update("MysqlDAO.datasetTableCreate", datatable); | |
132 | + } | |
133 | + | |
134 | + @Override | |
135 | + public int datasetDefaultTableCreate(DataTable datatable) throws Exception { | |
136 | + return dbUtil.getTemplate().update("MysqlDAO.datasetDefaultTableCreate", datatable); | |
137 | + } | |
138 | + | |
139 | + @Override | |
140 | + public void datasetDataUpdate(DataTable datatable) throws Exception { | |
141 | + dbUtil.getTemplate().update("MysqlDAO.datasetDataUpdate", datatable); | |
142 | + } | |
143 | + | |
144 | + @Override | |
145 | + public void datasetDataDelete(DataTable datatable) throws Exception { | |
146 | + dbUtil.getTemplate().delete("MysqlDAO.datasetDataDelete", datatable); | |
147 | + } | |
148 | + | |
149 | + @Override | |
150 | + public int duplicateCheckTableName(Map info) throws Exception { | |
151 | + return dbUtil.getTemplate().selectOne("MysqlDAO.duplicateCheckTableName", info); | |
152 | + } | |
153 | + | |
154 | + @Override | |
155 | + public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception { | |
156 | + return dbUtil.getTemplate().selectList("MysqlDAO.getRowData", dataTable); | |
157 | + } | |
158 | + | |
159 | + @Override | |
160 | + public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception { | |
161 | + return dbUtil.getTemplate().selectList("MysqlDAO.getRowDataAll", dataTable); | |
162 | + } | |
163 | + | |
164 | + @Override | |
165 | + public int getRowDataTotalRows(DataTable dataTable) throws Exception { | |
166 | + return dbUtil.getTemplate().selectOne("MysqlDAO.getRowDataTotalRows", dataTable); | |
167 | + } | |
168 | + | |
169 | + @Override | |
170 | + public int emptyDataset(DataTable dataTable) throws Exception { | |
171 | + return dbUtil.getTemplate().delete("MysqlDAO.emptyDataset", dataTable); | |
172 | + } | |
173 | + | |
174 | + @Override | |
175 | + public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception { | |
176 | + return dbUtil.getTemplate().update("MysqlDAO.tableColumnChange", tableBasicInfo); | |
177 | + } | |
178 | + | |
179 | + @Override | |
180 | + public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception { | |
181 | + return dbUtil.getTemplate().update("MysqlDAO.changePromaryKey", tableBasicInfo); | |
182 | + } | |
183 | + | |
184 | + @Override | |
185 | + public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception { | |
186 | + return dbUtil.getTemplate().update("MysqlDAO.createAutoIncrement", tableBasicInfo); | |
187 | + } | |
188 | + | |
189 | + @Override | |
190 | + public void updateTableMetaInfo(DataTable dataTable) throws Exception { | |
191 | + dbUtil.getTemplate().update("MysqlDAO.updateTableMetaInfo", dataTable); | |
192 | + } | |
193 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/OracleDAO.java
... | ... | @@ -0,0 +1,194 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.dao; | |
2 | + | |
3 | +import com.fasterxml.jackson.core.type.TypeReference; | |
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
5 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig; | |
6 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
7 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo; | |
8 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
9 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
10 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
11 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
12 | +import org.apache.ibatis.mapping.ParameterMapping; | |
13 | +import org.mybatis.spring.SqlSessionTemplate; | |
14 | +import org.springframework.stereotype.Repository; | |
15 | + | |
16 | +import java.util.*; | |
17 | + | |
18 | +/** | |
19 | + * @author 박민혁 | |
20 | + * @since 2024.03.28 | |
21 | + * | |
22 | + * Oracle 접속 모듈에 관련된 SQL문에 접근하는 DAO Class입니다. | |
23 | + */ | |
24 | +@Repository | |
25 | +public class OracleDAO extends DatabaseDAO { | |
26 | + public OracleDAO(){} | |
27 | + | |
28 | + public OracleDAO(ConnectionDB db) throws Exception{ | |
29 | + this.createConnector(db); | |
30 | + } | |
31 | + | |
32 | + private DBConnectionConfig dbUtil = null; | |
33 | + | |
34 | + public DBConnectionConfig getDbUtil() { | |
35 | + return dbUtil; | |
36 | + } | |
37 | + public void setDbUtil(DBConnectionConfig dbUtil) { | |
38 | + this.dbUtil = dbUtil; | |
39 | + } | |
40 | + | |
41 | + @Override | |
42 | + public void createConnector (ConnectionDB db) throws Exception { | |
43 | + dbUtil = new DBConnectionConfig(); | |
44 | + dbUtil.mybatisSqlTemplateCreate(db); | |
45 | + } | |
46 | + | |
47 | + @Override | |
48 | + public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception { | |
49 | + try { | |
50 | + return dbUtil.getTemplate().selectList("OracleDAO.getDBConnectionTableList", db); | |
51 | + } catch (Exception e) { | |
52 | + return new ArrayList<Dataset>(); | |
53 | + } | |
54 | + } | |
55 | + | |
56 | + @Override | |
57 | + public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception { | |
58 | + return dbUtil.getTemplate().selectList("OracleDAO.getDBConnectionTableColumnList", dataset); | |
59 | + } | |
60 | + | |
61 | + @Override | |
62 | + public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList(DataTable datatable) throws Exception { | |
63 | + return dbUtil.getTemplate().selectList("OracleDAO.getDBConnectionTableDataList", datatable); | |
64 | + } | |
65 | + | |
66 | + @Override | |
67 | + public int getDBConnectionTableDataTotalRows(DataTable datatable) throws Exception { | |
68 | + return dbUtil.getTemplate().selectOne("OracleDAO.getDBConnectionTableDataTotalRows", datatable); | |
69 | + } | |
70 | + | |
71 | + @Override | |
72 | + public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList(DataTable datatable) throws Exception { | |
73 | + return dbUtil.getTemplate().selectList("OracleDAO.getDBConnectionCustomQueryDataList", datatable); | |
74 | + } | |
75 | + | |
76 | + @Override | |
77 | + public int executeCustomQuery(DataTable datatable) throws Exception { | |
78 | + return dbUtil.getTemplate().update("OracleDAO.executeCustomQuery", datatable); | |
79 | + } | |
80 | + | |
81 | + @Override | |
82 | + public int getDBConnectionCustomQueryDataTotalRows(DataTable datatable) throws Exception { | |
83 | + return dbUtil.getTemplate().selectOne("OracleDAO.getDBConnectionCustomQueryDataTotalRows", datatable); | |
84 | + } | |
85 | + | |
86 | + @Override | |
87 | + public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList(DataTable datatable) throws Exception { | |
88 | + return dbUtil.getTemplate().selectList("OracleDAO.getDBCollectionQueryDataList", datatable); | |
89 | + } | |
90 | + | |
91 | + @Override | |
92 | + public int getDBCollectionQueryDataTotalRows(DataTable datatable) throws Exception { | |
93 | + return dbUtil.getTemplate().selectOne("OracleDAO.getDBCollectionQueryDataTotalRows", datatable); | |
94 | + } | |
95 | + | |
96 | + @Override | |
97 | + public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception { | |
98 | + return dbUtil.getTemplate().selectOne("OracleDAO.getCustomQueryPrimaryOverlapCount", datatable); | |
99 | + } | |
100 | + | |
101 | + @Override | |
102 | + public void dbConnectionClose() throws Exception { | |
103 | + dbUtil.close(); | |
104 | + } | |
105 | + | |
106 | + @Override | |
107 | + public String getQuery(String id, Object parameter) throws Exception { | |
108 | + SqlSessionTemplate template = dbUtil.getTemplate(); | |
109 | + | |
110 | + id = "OracleDAO." + id; | |
111 | + | |
112 | + String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql(); | |
113 | + List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings(); | |
114 | + | |
115 | + ObjectMapper mapper = new ObjectMapper(); | |
116 | + String json = mapper.writeValueAsString(parameter); | |
117 | + HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){}); | |
118 | + for (ParameterMapping par : paramMap) { | |
119 | + String param = StringUtil.toString(params.get(par.getProperty())); | |
120 | + if(parameter == null) | |
121 | + sql = sql.replaceFirst("\\?", "NULL"); | |
122 | + else | |
123 | + sql = sql.replaceFirst("\\?", "'" + param + "'"); | |
124 | + } | |
125 | + | |
126 | + return sql; | |
127 | + } | |
128 | + | |
129 | + @Override | |
130 | + public int datasetTableCreate(DataTable datatable) throws Exception { | |
131 | + return dbUtil.getTemplate().update("OracleDAO.datasetTableCreate", datatable); | |
132 | + } | |
133 | + | |
134 | + @Override | |
135 | + public int datasetDefaultTableCreate(DataTable datatable) throws Exception { | |
136 | + return dbUtil.getTemplate().update("OracleDAO.datasetDefaultTableCreate", datatable); | |
137 | + } | |
138 | + | |
139 | + @Override | |
140 | + public void datasetDataUpdate(DataTable datatable) throws Exception { | |
141 | + dbUtil.getTemplate().update("OracleDAO.datasetDataUpdate", datatable); | |
142 | + } | |
143 | + | |
144 | + @Override | |
145 | + public void datasetDataDelete(DataTable datatable) throws Exception { | |
146 | + dbUtil.getTemplate().delete("OracleDAO.datasetDataDelete", datatable); | |
147 | + } | |
148 | + | |
149 | + @Override | |
150 | + public int duplicateCheckTableName(Map info) throws Exception { | |
151 | + return dbUtil.getTemplate().selectOne("OracleDAO.duplicateCheckTableName", info); | |
152 | + } | |
153 | + | |
154 | + @Override | |
155 | + public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception { | |
156 | + return dbUtil.getTemplate().selectList("OracleDAO.getRowData", dataTable); | |
157 | + } | |
158 | + | |
159 | + @Override | |
160 | + public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception { | |
161 | + return dbUtil.getTemplate().selectList("OracleDAO.getRowDataAll", dataTable); | |
162 | + } | |
163 | + | |
164 | + @Override | |
165 | + public int getRowDataTotalRows(DataTable dataTable) throws Exception { | |
166 | + return dbUtil.getTemplate().selectOne("OracleDAO.getRowDataTotalRows", dataTable); | |
167 | + } | |
168 | + | |
169 | + @Override | |
170 | + public int emptyDataset(DataTable dataTable) throws Exception { | |
171 | + return dbUtil.getTemplate().delete("OracleDAO.emptyDataset", dataTable); | |
172 | + } | |
173 | + | |
174 | + @Override | |
175 | + public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception { | |
176 | + return dbUtil.getTemplate().update("OracleDAO.tableColumnChange", tableBasicInfo); | |
177 | + } | |
178 | + | |
179 | + @Override | |
180 | + public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception { | |
181 | + return dbUtil.getTemplate().update("OracleDAO.changePromaryKey", tableBasicInfo); | |
182 | + } | |
183 | + | |
184 | + @Override | |
185 | + public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception { | |
186 | + return dbUtil.getTemplate().update("OracleDAO.createAutoIncrement", tableBasicInfo); | |
187 | + } | |
188 | + | |
189 | + @Override | |
190 | + public void updateTableMetaInfo(DataTable dataTable) throws Exception { | |
191 | + dbUtil.getTemplate().update("OracleDAO.updateTableMetaInfo", dataTable); | |
192 | + } | |
193 | + | |
194 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/PostgresqlDAO.java
... | ... | @@ -0,0 +1,228 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.dao; | |
2 | + | |
3 | + | |
4 | +import java.util.ArrayList; | |
5 | +import java.util.HashMap; | |
6 | +import java.util.LinkedHashMap; | |
7 | +import java.util.List; | |
8 | +import java.util.Map; | |
9 | + | |
10 | +import org.apache.ibatis.mapping.ParameterMapping; | |
11 | +import org.mybatis.spring.SqlSessionTemplate; | |
12 | + | |
13 | +import com.fasterxml.jackson.core.type.TypeReference; | |
14 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
15 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig; | |
16 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
17 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo; | |
18 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
19 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
20 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
21 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
22 | + | |
23 | + | |
24 | + | |
25 | +public class PostgresqlDAO extends DatabaseDAO { | |
26 | + | |
27 | + public PostgresqlDAO () {} | |
28 | + | |
29 | + public PostgresqlDAO (ConnectionDB db) throws Exception { | |
30 | + this.createConnector(db); | |
31 | + } | |
32 | + | |
33 | + private DBConnectionConfig dbUtil = null; | |
34 | + | |
35 | + public DBConnectionConfig getDbUtil() { | |
36 | + return dbUtil; | |
37 | + } | |
38 | + public void setDbUtil(DBConnectionConfig dbUtil) { | |
39 | + this.dbUtil = dbUtil; | |
40 | + } | |
41 | + | |
42 | + | |
43 | + @Override | |
44 | + public void createConnector(ConnectionDB db) throws Exception { | |
45 | + // TODO Auto-generated method stub | |
46 | + dbUtil = new DBConnectionConfig(); | |
47 | + dbUtil.mybatisSqlTemplateCreate(db); | |
48 | + } | |
49 | + | |
50 | + @Override | |
51 | + public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception { | |
52 | + // TODO Auto-generated method stub | |
53 | + try { | |
54 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBConnectionTableList", db); | |
55 | + } catch (Exception e) { | |
56 | + return new ArrayList<Dataset>(); | |
57 | + } | |
58 | + } | |
59 | + | |
60 | + @Override | |
61 | + public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception { | |
62 | + // TODO Auto-generated method stub | |
63 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBConnectionTableColumnList", dataset); | |
64 | + } | |
65 | + | |
66 | + @Override | |
67 | + public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList(DataTable datatable) throws Exception { | |
68 | + // TODO Auto-generated method stub | |
69 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBConnectionTableDataList", datatable); | |
70 | + } | |
71 | + | |
72 | + @Override | |
73 | + public int getDBConnectionTableDataTotalRows(DataTable datatable) throws Exception { | |
74 | + // TODO Auto-generated method stub | |
75 | + return dbUtil.getTemplate().selectOne("PostgresqlDAO.getDBConnectionTableDataTotalRows", datatable); | |
76 | + } | |
77 | + | |
78 | + @Override | |
79 | + public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList(DataTable datatable) | |
80 | + throws Exception { | |
81 | + // TODO Auto-generated method stub | |
82 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBConnectionCustomQueryDataList", datatable); | |
83 | + } | |
84 | + | |
85 | + @Override | |
86 | + public int executeCustomQuery(DataTable datatable) throws Exception { | |
87 | + // TODO Auto-generated method stub | |
88 | + return dbUtil.getTemplate().update("PostgresqlDAO.executeCustomQueryDataList", datatable); | |
89 | + } | |
90 | + | |
91 | + @Override | |
92 | + public int getDBConnectionCustomQueryDataTotalRows(DataTable datatable) throws Exception { | |
93 | + // TODO Auto-generated method stub | |
94 | + return dbUtil.getTemplate().selectOne("PostgresqlDAO.getDBConnectionCustomQueryDataTotalRows", datatable); | |
95 | + } | |
96 | + | |
97 | + @Override | |
98 | + public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList(DataTable datatable) throws Exception { | |
99 | + // TODO Auto-generated method stub | |
100 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getDBCollectionQueryDataList", datatable); | |
101 | + } | |
102 | + | |
103 | + @Override | |
104 | + public int getDBCollectionQueryDataTotalRows(DataTable datatable) throws Exception { | |
105 | + // TODO Auto-generated method stub | |
106 | + return dbUtil.getTemplate().selectOne("PostgresqlDAO.getDBCollectionQueryDataTotalRows", datatable); | |
107 | + } | |
108 | + | |
109 | + @Override | |
110 | + public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception { | |
111 | + // TODO Auto-generated method stub | |
112 | + return dbUtil.getTemplate().selectOne("getCustomQueryPrimaryOverlapCount.getCustomQueryPrimaryOverlapCount", datatable); | |
113 | + } | |
114 | + | |
115 | + @Override | |
116 | + public void dbConnectionClose() throws Exception { | |
117 | + dbUtil.close(); | |
118 | + } | |
119 | + | |
120 | + @Override | |
121 | + public String getQuery(String id, Object parameter) throws Exception { | |
122 | + SqlSessionTemplate template = dbUtil.getTemplate(); | |
123 | + | |
124 | + id = "PostgresqlDAO." + id; | |
125 | + | |
126 | + String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql(); | |
127 | + List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings(); | |
128 | + | |
129 | + ObjectMapper mapper = new ObjectMapper(); | |
130 | + String json = mapper.writeValueAsString(parameter); | |
131 | + HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){}); | |
132 | + for (ParameterMapping par : paramMap) { | |
133 | + String param = StringUtil.toString(params.get(par.getProperty())); | |
134 | + if(parameter == null) | |
135 | + sql = sql.replaceFirst("\\?", "NULL"); | |
136 | + else | |
137 | + sql = sql.replaceFirst("\\?", "'" + param + "'"); | |
138 | + } | |
139 | + | |
140 | + return sql; | |
141 | + } | |
142 | + | |
143 | + @Override | |
144 | + public int datasetTableCreate(DataTable datatable) throws Exception { | |
145 | + // TODO Auto-generated method stub | |
146 | + return dbUtil.getTemplate().update("PostgresqlDAO.datasetTableCreate", datatable); | |
147 | + } | |
148 | + | |
149 | + @Override | |
150 | + public int datasetDefaultTableCreate(DataTable datatable) throws Exception { | |
151 | + // TODO Auto-generated method stub | |
152 | + return dbUtil.getTemplate().update("PostgresqlDAO.datasetDefaultTableCreate", datatable); | |
153 | + } | |
154 | + | |
155 | + @Override | |
156 | + public void datasetDataUpdate(DataTable datatable) throws Exception { | |
157 | + // TODO Auto-generated method stub | |
158 | + dbUtil.getTemplate().update("PostgresqlDAO.datasetDataUpdate", datatable); | |
159 | + } | |
160 | + | |
161 | + @Override | |
162 | + public void datasetDataDelete(DataTable datatable) throws Exception { | |
163 | + // TODO Auto-generated method stub | |
164 | + dbUtil.getTemplate().update("PostgresqlDAO.datasetDataDelete", datatable); | |
165 | + } | |
166 | + | |
167 | + @Override | |
168 | + public int duplicateCheckTableName(Map info) throws Exception { | |
169 | + // TODO Auto-generated method stub | |
170 | + return dbUtil.getTemplate().selectOne("PostgresqlDAO.duplicateCheckTableName", info); | |
171 | + } | |
172 | + | |
173 | + @Override | |
174 | + public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception { | |
175 | + // TODO Auto-generated method stub | |
176 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getRowData", dataTable); | |
177 | + } | |
178 | + | |
179 | + @Override | |
180 | + public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception { | |
181 | + // TODO Auto-generated method stub | |
182 | + | |
183 | + ObjectMapper mapper = new ObjectMapper(); | |
184 | + | |
185 | + | |
186 | + return dbUtil.getTemplate().selectList("PostgresqlDAO.getRowDataAll", dataTable); | |
187 | + } | |
188 | + | |
189 | + @Override | |
190 | + public int getRowDataTotalRows(DataTable dataTable) throws Exception { | |
191 | + // TODO Auto-generated method stub | |
192 | + return dbUtil.getTemplate().selectOne("PostgresqlDAO.getRowDataTotalRows", dataTable); | |
193 | + } | |
194 | + | |
195 | + @Override | |
196 | + public int emptyDataset(DataTable dataTable) throws Exception { | |
197 | + // TODO Auto-generated method stub | |
198 | + return dbUtil.getTemplate().delete("PostgresqlDAO.emptyDataset", dataTable); | |
199 | + } | |
200 | + | |
201 | + @Override | |
202 | + public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception { | |
203 | + // TODO Auto-generated method stub | |
204 | + ObjectMapper mapper = new ObjectMapper(); | |
205 | + | |
206 | + | |
207 | + return dbUtil.getTemplate().update("PostgresqlDAO.tableColumnChange", tableBasicInfo); | |
208 | + } | |
209 | + | |
210 | + @Override | |
211 | + public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception { | |
212 | + // TODO Auto-generated method stub | |
213 | + return dbUtil.getTemplate().update("PostgresqlDAO.changePromaryKey", tableBasicInfo); | |
214 | + } | |
215 | + | |
216 | + @Override | |
217 | + public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception { | |
218 | + // TODO Auto-generated method stub | |
219 | + return dbUtil.getTemplate().update("PostgresqlDAO.createAutoIncrement", tableBasicInfo); | |
220 | + } | |
221 | + | |
222 | + | |
223 | + @Override | |
224 | + public void updateTableMetaInfo(DataTable dataTable) throws Exception { | |
225 | + dbUtil.getTemplate().update("PostgresqlDAO.updateTableMetaInfo", dataTable); | |
226 | + | |
227 | + } | |
228 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/dao/TiberoDAO.java
... | ... | @@ -0,0 +1,193 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.dao; | |
2 | + | |
3 | +import com.fasterxml.jackson.core.type.TypeReference; | |
4 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
5 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DBConnectionConfig; | |
6 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
7 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo; | |
8 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
9 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
10 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
11 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
12 | +import org.apache.ibatis.mapping.ParameterMapping; | |
13 | +import org.mybatis.spring.SqlSessionTemplate; | |
14 | +import org.springframework.stereotype.Repository; | |
15 | + | |
16 | +import java.util.*; | |
17 | + | |
18 | +/** | |
19 | + * @author 박민혁 | |
20 | + * @since 2024.04.08 | |
21 | + * | |
22 | + * Tebero 접속 모듈에 관련된 SQL문에 접근하는 DAO Class입니다. | |
23 | + */ | |
24 | +@Repository | |
25 | +public class TiberoDAO extends DatabaseDAO{ | |
26 | + public TiberoDAO(){} | |
27 | + | |
28 | + public TiberoDAO(ConnectionDB db) throws Exception{ | |
29 | + this.createConnector(db); | |
30 | + } | |
31 | + | |
32 | + private DBConnectionConfig dbUtil = null; | |
33 | + | |
34 | + public DBConnectionConfig getDbUtil() { | |
35 | + return dbUtil; | |
36 | + } | |
37 | + public void setDbUtil(DBConnectionConfig dbUtil) { | |
38 | + this.dbUtil = dbUtil; | |
39 | + } | |
40 | + | |
41 | + @Override | |
42 | + public void createConnector(ConnectionDB db) throws Exception { | |
43 | + dbUtil = new DBConnectionConfig(); | |
44 | + dbUtil.mybatisSqlTemplateCreate(db); | |
45 | + } | |
46 | + | |
47 | + @Override | |
48 | + public List<Dataset> getDBConnectionTableList(ConnectionDB db) throws Exception { | |
49 | + try { | |
50 | + return dbUtil.getTemplate().selectList("TiberoDAO.getDBConnectionTableList", db); | |
51 | + } catch (Exception e) { | |
52 | + return new ArrayList<Dataset>(); | |
53 | + } | |
54 | + } | |
55 | + | |
56 | + @Override | |
57 | + public List<ColumnData> getDBConnectionTableColumnList(Dataset dataset) throws Exception { | |
58 | + return dbUtil.getTemplate().selectList("TiberoDAO.getDBConnectionTableColumnList", dataset); | |
59 | + } | |
60 | + | |
61 | + @Override | |
62 | + public List<LinkedHashMap<String, Object>> getDBConnectionTableDataList(DataTable datatable) throws Exception { | |
63 | + return dbUtil.getTemplate().selectList("TiberoDAO.getDBConnectionTableDataList", datatable); | |
64 | + } | |
65 | + | |
66 | + @Override | |
67 | + public int getDBConnectionTableDataTotalRows(DataTable datatable) throws Exception { | |
68 | + return dbUtil.getTemplate().selectOne("TiberoDAO.getDBConnectionTableDataTotalRows", datatable); | |
69 | + } | |
70 | + | |
71 | + @Override | |
72 | + public List<LinkedHashMap<String, Object>> getDBConnectionCustomQueryDataList(DataTable datatable) throws Exception { | |
73 | + return dbUtil.getTemplate().selectList("TiberoDAO.getDBConnectionCustomQueryDataList", datatable); | |
74 | + } | |
75 | + | |
76 | + @Override | |
77 | + public int executeCustomQuery(DataTable datatable) throws Exception { | |
78 | + return dbUtil.getTemplate().update("TiberoDAO.executeCustomQuery", datatable); | |
79 | + } | |
80 | + | |
81 | + @Override | |
82 | + public int getDBConnectionCustomQueryDataTotalRows(DataTable datatable) throws Exception { | |
83 | + return dbUtil.getTemplate().selectOne("TiberoDAO.getDBConnectionCustomQueryDataTotalRows", datatable); | |
84 | + } | |
85 | + | |
86 | + @Override | |
87 | + public List<LinkedHashMap<String, Object>> getDBCollectionQueryDataList(DataTable datatable) throws Exception { | |
88 | + return dbUtil.getTemplate().selectList("TiberoDAO.getDBCollectionQueryDataList", datatable); | |
89 | + } | |
90 | + | |
91 | + @Override | |
92 | + public int getDBCollectionQueryDataTotalRows(DataTable datatable) throws Exception { | |
93 | + return dbUtil.getTemplate().selectOne("TiberoDAO.getDBCollectionQueryDataTotalRows", datatable); | |
94 | + } | |
95 | + | |
96 | + @Override | |
97 | + public int getCustomQueryPrimaryOverlapCount(DataTable datatable) throws Exception { | |
98 | + return dbUtil.getTemplate().selectOne("TiberoDAO.getCustomQueryPrimaryOverlapCount", datatable); | |
99 | + } | |
100 | + | |
101 | + @Override | |
102 | + public void dbConnectionClose() throws Exception { | |
103 | + dbUtil.close(); | |
104 | + } | |
105 | + | |
106 | + @Override | |
107 | + public String getQuery(String id, Object parameter) throws Exception { | |
108 | + SqlSessionTemplate template = dbUtil.getTemplate(); | |
109 | + | |
110 | + id = "TiberoDAO." + id; | |
111 | + | |
112 | + String sql = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getSql(); | |
113 | + List<ParameterMapping> paramMap = template.getConfiguration().getMappedStatement(id).getBoundSql(parameter).getParameterMappings(); | |
114 | + | |
115 | + ObjectMapper mapper = new ObjectMapper(); | |
116 | + String json = mapper.writeValueAsString(parameter); | |
117 | + HashMap<String, Object> params = mapper.readValue(json, new TypeReference<HashMap<String, Object>>(){}); | |
118 | + for (ParameterMapping par : paramMap) { | |
119 | + String param = StringUtil.toString(params.get(par.getProperty())); | |
120 | + if(parameter == null) | |
121 | + sql = sql.replaceFirst("\\?", "NULL"); | |
122 | + else | |
123 | + sql = sql.replaceFirst("\\?", "'" + param + "'"); | |
124 | + } | |
125 | + | |
126 | + return sql; | |
127 | + } | |
128 | + | |
129 | + @Override | |
130 | + public int datasetTableCreate(DataTable datatable) throws Exception { | |
131 | + return dbUtil.getTemplate().update("TiberoDAO.datasetTableCreate", datatable); | |
132 | + } | |
133 | + | |
134 | + @Override | |
135 | + public int datasetDefaultTableCreate(DataTable datatable) throws Exception { | |
136 | + return dbUtil.getTemplate().update("TiberoDAO.datasetDefaultTableCreate", datatable); | |
137 | + } | |
138 | + | |
139 | + @Override | |
140 | + public void datasetDataUpdate(DataTable datatable) throws Exception { | |
141 | + dbUtil.getTemplate().update("TiberoDAO.datasetDataUpdate", datatable); | |
142 | + } | |
143 | + | |
144 | + @Override | |
145 | + public void datasetDataDelete(DataTable datatable) throws Exception { | |
146 | + dbUtil.getTemplate().delete("TiberoDAO.datasetDataDelete", datatable); | |
147 | + } | |
148 | + | |
149 | + @Override | |
150 | + public int duplicateCheckTableName(Map info) throws Exception { | |
151 | + return dbUtil.getTemplate().selectOne("TiberoDAO.duplicateCheckTableName", info); | |
152 | + } | |
153 | + | |
154 | + @Override | |
155 | + public List<LinkedHashMap<String, Object>> getRowData(DataTable dataTable) throws Exception { | |
156 | + return dbUtil.getTemplate().selectList("TiberoDAO.getRowData", dataTable); | |
157 | + } | |
158 | + | |
159 | + @Override | |
160 | + public List<LinkedHashMap<String, Object>> getRowDataAll(DataTable dataTable) throws Exception { | |
161 | + return dbUtil.getTemplate().selectList("TiberoDAO.getRowDataAll", dataTable); | |
162 | + } | |
163 | + | |
164 | + @Override | |
165 | + public int getRowDataTotalRows(DataTable dataTable) throws Exception { | |
166 | + return dbUtil.getTemplate().selectOne("TiberoDAO.getRowDataTotalRows", dataTable); | |
167 | + } | |
168 | + | |
169 | + @Override | |
170 | + public int emptyDataset(DataTable dataTable) throws Exception { | |
171 | + return dbUtil.getTemplate().delete("TiberoDAO.emptyDataset", dataTable); | |
172 | + } | |
173 | + | |
174 | + @Override | |
175 | + public int tableColumnChange(TableBasicInfo tableBasicInfo) throws Exception { | |
176 | + return dbUtil.getTemplate().update("TiberoDAO.tableColumnChange", tableBasicInfo); | |
177 | + } | |
178 | + | |
179 | + @Override | |
180 | + public int changePrimaryKey(TableBasicInfo tableBasicInfo) throws Exception { | |
181 | + return dbUtil.getTemplate().update("TiberoDAO.changePromaryKey", tableBasicInfo); | |
182 | + } | |
183 | + | |
184 | + @Override | |
185 | + public int createAutoIncrement(TableBasicInfo tableBasicInfo) throws Exception { | |
186 | + return dbUtil.getTemplate().update("TiberoDAO.createAutoIncrement", tableBasicInfo); | |
187 | + } | |
188 | + | |
189 | + @Override | |
190 | + public void updateTableMetaInfo(DataTable dataTable) throws Exception { | |
191 | + dbUtil.getTemplate().update("TiberoDAO.updateTableMetaInfo", dataTable); | |
192 | + } | |
193 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/util/DBConnectionConfig.java
... | ... | @@ -0,0 +1,180 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.util; | |
2 | + | |
3 | +import java.sql.SQLException; | |
4 | + | |
5 | +import org.mybatis.spring.SqlSessionFactoryBean; | |
6 | +import org.mybatis.spring.SqlSessionTemplate; | |
7 | +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; | |
8 | +import org.springframework.jdbc.datasource.DataSourceTransactionManager; | |
9 | + | |
10 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
11 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType; | |
12 | +import com.zaxxer.hikari.HikariDataSource; | |
13 | + | |
14 | +/** | |
15 | + * @author 김성원 | |
16 | + * @since 2024.01.02 | |
17 | + * | |
18 | + * 동적 데이터 베이스 연계 관리 클래스 입니다. | |
19 | + */ | |
20 | +public class DBConnectionConfig { | |
21 | + | |
22 | + //프로젝트 내부 Class Path 정보 | |
23 | + // 한개 logger.debug(pathMatchingResourcePatternResolver.getResource("절대경로 혹은 classpath:이하경로").getFile().getAbsolutePath()); | |
24 | + // 여러개 Resource[] resource = pathMatchingResourcePatternResolver.getResources("절대경로 혹은 classpath:이하경로"); | |
25 | + private final static PathMatchingResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); | |
26 | + | |
27 | + //동적 Mybatis 연계 - mybatis 설정 정보 파일 경로 | |
28 | + private final static String DYNAMIC_MYBATIS_CONFIG = "spring/mapper/mybatis-config.xml"; | |
29 | + | |
30 | + //동적 Mybatis 연계 - mybatis Mapper 문서 파일 경로 | |
31 | + private final static String DYNAMIC_MYBATIS_MAPPERS = "spring/mapper/sql/*-SQL.xml"; | |
32 | + | |
33 | + private HikariDataSource dataSource = null; | |
34 | + | |
35 | + private SqlSessionFactoryBean sqlSession = null; | |
36 | + | |
37 | + private SqlSessionTemplate template = null; | |
38 | + | |
39 | + private DataSourceTransactionManager dataSourceTransaction = null; | |
40 | + | |
41 | + public HikariDataSource getDataSource() { | |
42 | + return dataSource; | |
43 | + } | |
44 | + | |
45 | + public void setDataSource(HikariDataSource dataSource) { | |
46 | + this.dataSource = dataSource; | |
47 | + } | |
48 | + | |
49 | + public SqlSessionFactoryBean getSqlSession() { | |
50 | + return sqlSession; | |
51 | + } | |
52 | + | |
53 | + public void setSqlSession(SqlSessionFactoryBean sqlSession) { | |
54 | + this.sqlSession = sqlSession; | |
55 | + } | |
56 | + | |
57 | + public SqlSessionTemplate getTemplate() { | |
58 | + return template; | |
59 | + } | |
60 | + | |
61 | + public void setTemplate(SqlSessionTemplate template) { | |
62 | + this.template = template; | |
63 | + } | |
64 | + | |
65 | + | |
66 | + /** | |
67 | + * @author 김성원 | |
68 | + * @since 2024.01.08 | |
69 | + * | |
70 | + * 동적 DB + Mybatis 객체 생성 -> Mapper에 접근하기위한 SQL 템플릿 반환 | |
71 | + */ | |
72 | + public SqlSessionTemplate mybatisSqlTemplateCreate (ConnectionDB db) { | |
73 | + dataSource = dataSourceCreate(db); | |
74 | + sqlSession = sqlSessionCreate(dataSource); | |
75 | + template = sqlSessionTemplateCreate(sqlSession); | |
76 | + dataSourceTransaction = getTransaction(dataSource); | |
77 | + | |
78 | + return template; | |
79 | + } | |
80 | + | |
81 | + /** | |
82 | + * @author 김성원 | |
83 | + * @since 2024.01.08 | |
84 | + * | |
85 | + * 동적 DataSource 생성 | |
86 | + */ | |
87 | + public HikariDataSource dataSourceCreate (ConnectionDB db) { | |
88 | + dataSource = null; | |
89 | + try { | |
90 | + dataSource = new HikariDataSource(); | |
91 | + DatabaseType dataBaseType = db.getDatabaseType(); | |
92 | + dataSource.setDriverClassName(dataBaseType.getDriverClassName()); | |
93 | + dataSource.setJdbcUrl(dataBaseType.getUrl(db)); | |
94 | + | |
95 | + dataSource.setUsername(db.getUserId()); | |
96 | + dataSource.setPassword(db.getUserPassword()); | |
97 | + } catch (Exception e) { | |
98 | + e.printStackTrace(); | |
99 | + } | |
100 | + | |
101 | + return dataSource; | |
102 | + } | |
103 | + | |
104 | + /** | |
105 | + * @author 김성원 | |
106 | + * @since 2024.01.08 | |
107 | + * | |
108 | + * 동적으로 생성한 DataSource정보와 Mybatis 설정 정보 연계 생성 | |
109 | + */ | |
110 | + private SqlSessionFactoryBean sqlSessionCreate (HikariDataSource dataSource) { | |
111 | + try { | |
112 | + sqlSession = new SqlSessionFactoryBean(); | |
113 | + sqlSession.setDataSource(dataSource); | |
114 | + sqlSession.setConfigLocation(resourceResolver.getResource(DYNAMIC_MYBATIS_CONFIG)); | |
115 | + sqlSession.setMapperLocations(resourceResolver.getResources(DYNAMIC_MYBATIS_MAPPERS)); | |
116 | + } catch (Exception e) { | |
117 | + e.printStackTrace(); | |
118 | + } | |
119 | + | |
120 | + return sqlSession; | |
121 | + } | |
122 | + | |
123 | + /** | |
124 | + * @author 김성원 | |
125 | + * @since 2024.01.08 | |
126 | + * | |
127 | + * 동적 Mybatis Mapper에 접근하기위한 SQL 템플릿 생성 | |
128 | + */ | |
129 | + private SqlSessionTemplate sqlSessionTemplateCreate (SqlSessionFactoryBean sqlSession) { | |
130 | + try { | |
131 | + template = new SqlSessionTemplate(sqlSession.getObject()); | |
132 | + template.clearCache(); | |
133 | + } catch (Exception e) { | |
134 | + e.printStackTrace(); | |
135 | + } | |
136 | + | |
137 | + return template; | |
138 | + } | |
139 | + | |
140 | + | |
141 | + /** | |
142 | + * @author 김성원 | |
143 | + * @since 2024.01.08 | |
144 | + * | |
145 | + * 동적 Mybatis Mapper에 접근하기위한 SQL 템플릿 생성 | |
146 | + */ | |
147 | + private DataSourceTransactionManager getTransaction (HikariDataSource dataSource) { | |
148 | + | |
149 | + this.dataSourceTransaction = new DataSourceTransactionManager(dataSource); | |
150 | + | |
151 | + return dataSourceTransaction; | |
152 | + } | |
153 | + | |
154 | + | |
155 | + | |
156 | + /** | |
157 | + * @author 김성원 | |
158 | + * @since 2024.01.08 | |
159 | + * | |
160 | + * 커넥션 닫기 | |
161 | + */ | |
162 | + public void close() throws SQLException { | |
163 | + try { | |
164 | + if (dataSource != null) { | |
165 | + dataSource.evictConnection(dataSource.getConnection()); | |
166 | + if (dataSource.getConnection() != null) { | |
167 | + dataSource.getConnection().close(); | |
168 | + } | |
169 | + dataSource.close(); | |
170 | + } | |
171 | + }catch(Exception e) { | |
172 | + if (dataSource != null) { | |
173 | + dataSource.close(); | |
174 | + } | |
175 | + } | |
176 | + | |
177 | + } | |
178 | + | |
179 | + | |
180 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/util/DBConnectionUtil.java
... | ... | @@ -0,0 +1,762 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.util; | |
2 | + | |
3 | +import java.sql.Connection; | |
4 | +import java.sql.SQLException; | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.LinkedHashMap; | |
7 | +import java.util.List; | |
8 | +import java.util.Map; | |
9 | + | |
10 | +import com.takensoft.taken_bi_manager.common.connection.db.dao.*; | |
11 | +import org.slf4j.Logger; | |
12 | +import org.slf4j.LoggerFactory; | |
13 | +import org.springframework.transaction.annotation.Transactional; | |
14 | + | |
15 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
16 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.TableBasicInfo; | |
17 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
18 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
19 | +import com.takensoft.taken_bi_manager.common.vo.CheckMessage; | |
20 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType; | |
21 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
22 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
23 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
24 | + | |
25 | + | |
26 | + | |
27 | +/** | |
28 | + * @author 최정우 | |
29 | + * @since 2019.11.12 | |
30 | + * | |
31 | + * 데이터 수집 - DB 데이터 연계 관련 Util 입니다. | |
32 | + */ | |
33 | +@Transactional | |
34 | +public class DBConnectionUtil { | |
35 | + | |
36 | + private Logger logger = LoggerFactory.getLogger(DBConnectionUtil.class); | |
37 | + | |
38 | + /** | |
39 | + * @author 김성원 | |
40 | + * @since 2024.01.04 | |
41 | + * | |
42 | + * 데이터베이스 접속 모듈 DAO 객체 생성 메서드입니다. | |
43 | + */ | |
44 | + public DatabaseDAO createDatabaseDAO (ConnectionDB db) throws Exception { | |
45 | + | |
46 | + DatabaseDAO databaseDao= null; | |
47 | + | |
48 | + if (db.getDatabaseType() == DatabaseType.MYSQL) { | |
49 | + databaseDao = new MysqlDAO(db); | |
50 | + } else if (db.getDatabaseType() == DatabaseType.MARIADB) { | |
51 | + databaseDao = new MariadbDAO(db); | |
52 | + } else if (db.getDatabaseType() == DatabaseType.ORACLE) { | |
53 | + databaseDao = new OracleDAO(db); | |
54 | + } else if (db.getDatabaseType() == DatabaseType.MSSQL) { | |
55 | + databaseDao = new MssqlDAO(db); | |
56 | + } else if (db.getDatabaseType() == DatabaseType.TIBERO) { | |
57 | + // databaseDao = new TiberoDAO(db); | |
58 | + }else if (db.getDatabaseType() == DatabaseType.POSTGRESQL) { | |
59 | + return new PostgresqlDAO(db); | |
60 | + } else { | |
61 | + throw new Exception(); | |
62 | + } | |
63 | + return databaseDao; | |
64 | + } | |
65 | + | |
66 | + /** | |
67 | + * @author 김성원 | |
68 | + * @since 2024.01.04 | |
69 | + * | |
70 | + * DB 접속 테스트 입니다. | |
71 | + */ | |
72 | + public CheckMessage dbConnectionCheck (ConnectionDB dbCollection) throws Exception { | |
73 | + if(StringUtil.isEmpty(dbCollection.getConectIp()) == true) { | |
74 | + return new CheckMessage(false, "접속 IP를 입력해주세요"); | |
75 | + } else if(StringUtil.isEmpty(dbCollection.getConectPort()) == true) { | |
76 | + return new CheckMessage(false, "접속 Port를 입력해주세요"); | |
77 | + } else if(CommonUtil.isInt(dbCollection.getConectPort()) == false) { | |
78 | + return new CheckMessage(false, "접속 Port는 숫자로만 입력해주세요"); | |
79 | + } else if(StringUtil.isEmpty(dbCollection.getDatabaseNm()) == true) { | |
80 | + return new CheckMessage(false, "DB명을 입력해주세요"); | |
81 | + } else if(StringUtil.isEmpty(dbCollection.getConectIp()) == true) { | |
82 | + return new CheckMessage(false, "접속 ID를 입력해주세요."); | |
83 | + } else if(StringUtil.isEmpty(dbCollection.getUserPassword()) == true) { | |
84 | + return new CheckMessage(false, "접속 PW를 입력해주세요."); | |
85 | + } else { | |
86 | + /*if (CommonUtil.pingCheck(dbCollection.getIp()) == false) { | |
87 | + return new CheckMessage(false, "접속 IP(" + dbCollection.getIp() + ")와 연결할 수 없습니다"); | |
88 | + }*/ | |
89 | + if (CommonUtil.linkCheck(dbCollection.getConectIp(), Integer.parseInt(dbCollection.getConectPort())) == false) { | |
90 | + return new CheckMessage(false, "접속 IP(" + dbCollection.getConectIp() + ")의 Port(" + dbCollection.getConectPort() + ")와 연결할 수 없습니다"); | |
91 | + } | |
92 | + Connection connection = null; | |
93 | + DBConnectionConfig dbUtil = new DBConnectionConfig(); | |
94 | + try { | |
95 | + dbUtil.dataSourceCreate(dbCollection); | |
96 | + connection = dbUtil.getDataSource().getConnection(); | |
97 | + return new CheckMessage(true, "[" + dbCollection.getDatabaseType().getValue() + "] " + dbCollection.getDatabaseNm() + " 접속 성공"); | |
98 | + } catch (SQLException e) { | |
99 | + | |
100 | + return new CheckMessage(false, "접속 에러 : " + e.toString()); | |
101 | + } catch (Exception e) { | |
102 | + | |
103 | + return new CheckMessage(false, "접속 에러 : " + e.toString()); | |
104 | + } finally { | |
105 | + if (connection != null) { | |
106 | + try { | |
107 | + connection.close(); | |
108 | + } catch (Exception e) { | |
109 | + | |
110 | + return new CheckMessage(false, "접속 에러 : " + e.toString()); | |
111 | + } | |
112 | + } if (dbUtil != null) { | |
113 | + dbUtil.close(); | |
114 | + } | |
115 | + } | |
116 | + } | |
117 | + } | |
118 | + | |
119 | + /** | |
120 | + * @author 김성원 | |
121 | + * @since 2024.01.04 | |
122 | + * | |
123 | + * DB 접속 - 테이블 목록 조회 메소드 입니다. | |
124 | + */ | |
125 | + public List<Dataset> getDBConnectionTableList (ConnectionDB dbCollection , CheckMessage message) throws Exception { | |
126 | + message = dbConnectionCheck(dbCollection); | |
127 | + | |
128 | + if (message.isSuccess() == false) { | |
129 | + logger.info("getDbConnectionTableList DB연결실패 : " + message.getMessage()); | |
130 | + return new ArrayList<Dataset>(); | |
131 | + } | |
132 | + | |
133 | + List<Dataset> dbConnectionTableList = new ArrayList<Dataset>(); | |
134 | + | |
135 | + //DAO 인스턴스 생성 | |
136 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
137 | + | |
138 | + try { | |
139 | + //테이블 목록 조회 | |
140 | + dbConnectionTableList = databaseDAO.getDBConnectionTableList(dbCollection); | |
141 | + }catch (Exception e){ | |
142 | + message.setError(e.toString()); | |
143 | + } | |
144 | + finally { | |
145 | + //DB연결 종료 | |
146 | + databaseDAO.dbConnectionClose(); | |
147 | + } | |
148 | + | |
149 | + return dbConnectionTableList; | |
150 | + } | |
151 | + | |
152 | + /** | |
153 | + * @author 김성원 | |
154 | + * @since 2024.01.04 | |
155 | + * | |
156 | + * 커넥션된 데이터베이스의 테이블의 컬럼 정보 조회 (DB 기준 데이터 타입, 데이터 크기 등) | |
157 | + */ | |
158 | + public List<ColumnData> getDBConnectionTableColumnList(ConnectionDB dbCollection, Dataset dataset) throws Exception { | |
159 | + CheckMessage message = dbConnectionCheck(dbCollection); | |
160 | + | |
161 | + if (message.isSuccess() == false) { | |
162 | + logger.info("getDBConnectionTableColumnList DB연결실패 : " + message.getMessage()); | |
163 | + return new ArrayList<ColumnData>(); | |
164 | + } | |
165 | + | |
166 | + List<ColumnData> tableColumnList = new ArrayList<ColumnData>(); | |
167 | + | |
168 | + //DAO 인스턴스 생성 | |
169 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
170 | + | |
171 | + try { | |
172 | + //테이블 컬럼 목록 조회 | |
173 | + tableColumnList = databaseDAO.getDBConnectionTableColumnList(dataset); | |
174 | + }finally { | |
175 | + //DB연결 종료 | |
176 | + databaseDAO.dbConnectionClose(); | |
177 | + } | |
178 | + | |
179 | + return tableColumnList; | |
180 | + } | |
181 | + | |
182 | + /** | |
183 | + * @author 최정우 | |
184 | + * @since 2020.01.28 | |
185 | + * | |
186 | + * 커넥션된 데이터베이스의 테이블의 데이터에 대한 데이터 테이블 조회 메서드입니다. | |
187 | + */ | |
188 | + public void setDataTableByDBConnectionTable (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
189 | + CheckMessage message = dbConnectionCheck(dbCollection); | |
190 | + | |
191 | + if (message.isSuccess() == false) { | |
192 | + dataTable.setCheckMessage(message); | |
193 | + logger.info("setDataTableByDBConnectionTable DB연결실패 : " + message.getMessage()); | |
194 | + return; | |
195 | + } | |
196 | + | |
197 | + //DAO 인스턴스 생성 | |
198 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
199 | + dataTable.setIsUsePaging(true); | |
200 | + | |
201 | + int tableDataTotalRows = 0; | |
202 | + | |
203 | + List<LinkedHashMap<String, Object>> tableDataMapList = new ArrayList<LinkedHashMap<String, Object>>(); | |
204 | + | |
205 | + try { | |
206 | + | |
207 | + //테이블 기본 Select 정보(데이터베이스명, 테이블명) 입력 | |
208 | + Dataset dataset = new Dataset(); | |
209 | + | |
210 | + if (dbCollection.getDatabaseType() == DatabaseType.ORACLE) { | |
211 | + dataset.setDatabaseNm(dbCollection.getUserId()); | |
212 | + } else { | |
213 | + dataset.setDatabaseNm(dbCollection.getDatabaseNm()); | |
214 | + } | |
215 | + dataset.setTableNm(dataTable.getTableNm()); | |
216 | + | |
217 | + | |
218 | + //테이블 컬럼 목록 조회 | |
219 | + dataTable.setColumnDatas(databaseDAO.getDBConnectionTableColumnList(dataset));//테이블 컬럼 정보 set | |
220 | + dataTable.setColumnDatas( DataTypeUtil.convertDataTypeDbtoJavaList(dataTable.getColumnDatas(),dbCollection.getDatabaseType())); | |
221 | + | |
222 | + //테이블 데이터 조회 | |
223 | + if (dbCollection.getDatabaseType() == DatabaseType.ORACLE) { | |
224 | + dataTable.setDatabaseNm(dbCollection.getUserId()); | |
225 | + } | |
226 | + | |
227 | + tableDataMapList = databaseDAO.getDBConnectionTableDataList(dataTable); | |
228 | + dataTable.setRowData(CommonUtil.rowDataMapToList(tableDataMapList));//테이블 데이터 set | |
229 | + | |
230 | + //테이블 데이터 총 개수 조회 | |
231 | + tableDataTotalRows = databaseDAO.getDBConnectionTableDataTotalRows(dataTable); | |
232 | + dataTable.setTotalRows(tableDataTotalRows);//테이블 데이터 총 개수 set | |
233 | + | |
234 | + //SELECT 쿼리 생성 | |
235 | + if (dbCollection.getDatabaseType() == DatabaseType.MSSQL) { | |
236 | + dataTable.makeQuery(); | |
237 | + } else { | |
238 | + dataTable.setQuery(); | |
239 | + } | |
240 | + }catch(Exception e) { | |
241 | + | |
242 | + logger.error(e.toString()); | |
243 | + | |
244 | + }finally { | |
245 | + //DB연결 종료 | |
246 | + databaseDAO.dbConnectionClose(); | |
247 | + } | |
248 | + | |
249 | + //성공 메세지 입력 | |
250 | + dataTable.getCheckMessage().setSuccess(true); | |
251 | + dataTable.getCheckMessage().setMessage("(총 조회된 행수 " + tableDataTotalRows + "개 / 현재 조회된 데이터 수 " + tableDataMapList.size() + "개)"); | |
252 | + } | |
253 | + | |
254 | + /** | |
255 | + * @author 김성원 | |
256 | + * @since 2024.01.04 | |
257 | + * | |
258 | + * 커스텀 쿼리를 통한 dataTable setting (페이징사용 유무에 따라 페이징 처리 - {rowDatas, columnDatas, query(이미 존재함)}) | |
259 | + */ | |
260 | + public void setDataTableByDBConnectionCustomQuery (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
261 | + CheckMessage message = dbConnectionCheck(dbCollection); | |
262 | + | |
263 | + if (message.isSuccess() == false) { | |
264 | + dataTable.setCheckMessage(message); | |
265 | + logger.info("setDataTableByDBConnectionCustomQuery DB연결실패 : " + message.getMessage()); | |
266 | + return; | |
267 | + } | |
268 | + | |
269 | + int tableDataTotalRows = 0; | |
270 | + | |
271 | + List<LinkedHashMap<String, Object>> tableDataMapList = new ArrayList<LinkedHashMap<String, Object>>(); | |
272 | + | |
273 | + | |
274 | + //DAO 인스턴스 생성 | |
275 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
276 | + | |
277 | + try { | |
278 | + //테이블 데이터 조회 | |
279 | + tableDataMapList = databaseDAO.getDBConnectionCustomQueryDataList(dataTable); | |
280 | + | |
281 | + //DataTable에 조회된 데이터에서 첫번째 행 값의 컬럼 분리 후, columnDatas에 세팅 | |
282 | + //DataTable에 rowData 세팅 | |
283 | + if (tableDataMapList != null && tableDataMapList.size() > 0) { | |
284 | + | |
285 | + //테이블 데이터 set | |
286 | + dataTable.setRowData(CommonUtil.rowDataMapToList(tableDataMapList)); | |
287 | + | |
288 | + //컬럼명 set | |
289 | + List<ColumnData> columnDatas = new ArrayList<ColumnData>(); | |
290 | + LinkedHashMap<String, Object> map = tableDataMapList.get(0); | |
291 | + | |
292 | + for(String key : map.keySet()){ | |
293 | + ColumnData column = new ColumnData(); | |
294 | + column.setColumnNm(key); | |
295 | + column.setDisplyColumnNm(key); | |
296 | + column.setOrginlColumnNm(key); | |
297 | + // 데이터 타입 정의 기능 | |
298 | + column.dataTyDefine(map.get(key)); | |
299 | + columnDatas.add(column); | |
300 | + } | |
301 | + | |
302 | + dataTable.setColumnDatas(columnDatas); | |
303 | + } | |
304 | + | |
305 | + //테이블 데이터 총 개수 조회 | |
306 | + tableDataTotalRows = databaseDAO.getDBConnectionCustomQueryDataTotalRows(dataTable); | |
307 | + dataTable.setTotalRows(tableDataTotalRows);//테이블 데이터 총 개수 set | |
308 | + //성공 메세지 입력 | |
309 | + dataTable.getCheckMessage().setSuccess(true); | |
310 | + dataTable.getCheckMessage().setMessage("(총 조회된 행수 " + tableDataTotalRows + "개 / 현재 조회된 데이터 수 " + tableDataMapList.size() + "개)"); | |
311 | + }catch(Exception e) { | |
312 | + logger.error(e.toString()); | |
313 | + dataTable.getCheckMessage().setError(e.toString()); | |
314 | + throw new Exception(e); | |
315 | + }finally { | |
316 | + //DB연결 종료 | |
317 | + databaseDAO.dbConnectionClose(); | |
318 | + } | |
319 | + //DB연결 종료 | |
320 | + databaseDAO.dbConnectionClose(); | |
321 | + | |
322 | + | |
323 | + } | |
324 | + | |
325 | + | |
326 | + /** | |
327 | + * @author 김성원 | |
328 | + * @since 2024.01.04 | |
329 | + * | |
330 | + * 조회내용이 없는 실행형 커스텀 쿼리(update, delete 등) | |
331 | + */ | |
332 | + public int executeCustomQuery(ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
333 | + | |
334 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
335 | + | |
336 | + int result = 0; | |
337 | + try { | |
338 | + result = databaseDAO.executeCustomQuery(dataTable); | |
339 | + }catch(Exception e) { | |
340 | + | |
341 | + }finally{ | |
342 | + databaseDAO.dbConnectionClose(); | |
343 | + } | |
344 | + | |
345 | + return result; | |
346 | + } | |
347 | + | |
348 | + | |
349 | + /** | |
350 | + * @author 김성원 | |
351 | + * @since 2024.01.04 | |
352 | + * | |
353 | + * 커스텀 쿼리 지정된 PK로 테이블 생성이 가능한지 확인 | |
354 | + */ | |
355 | + public void setCustomQueryPrimaryCreatePossibleCheck (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
356 | + | |
357 | + if (dataTable.getColumnDatas() == null || dataTable.getColumnDatas().size() == 0) { | |
358 | + dataTable.getCheckMessage().setSuccess(false); | |
359 | + dataTable.getCheckMessage().setMessage("PK생성 가능 유무 검사 - 테이블을 생성할 컬럼이 없습니다."); | |
360 | + return; | |
361 | + } | |
362 | + | |
363 | + String primaryColumns = ""; | |
364 | + List<ColumnData> primaryColumnDatas = new ArrayList<ColumnData>(); | |
365 | + | |
366 | + for (int i = 0; i < dataTable.getColumnDatas().size(); i++) { | |
367 | + if (dataTable.getColumnDatas().get(i).isPkAt() == true) { | |
368 | + primaryColumns += ("[" + dataTable.getColumnDatas().get(i).getColumnNm() + "]"); | |
369 | + primaryColumnDatas.add(dataTable.getColumnDatas().get(i)); | |
370 | + } | |
371 | + } | |
372 | + | |
373 | + if (primaryColumnDatas.size() == 0) { | |
374 | + dataTable.getCheckMessage().setSuccess(true); | |
375 | + dataTable.getCheckMessage().setMessage("PK생성 가능 유무 검사 - PK로 지정한 컬럼이 없습니다.(검사통과)"); | |
376 | + return; | |
377 | + } | |
378 | + | |
379 | + //DB Connecting | |
380 | + CheckMessage message = dbConnectionCheck(dbCollection); | |
381 | + if (message.isSuccess() == false) { | |
382 | + dataTable.setCheckMessage(message); | |
383 | + logger.info("setDataTableByDBConnectionCustomQuery DB연결실패 : " + message.getMessage()); | |
384 | + return; | |
385 | + } | |
386 | + | |
387 | + //DAO 인스턴스 생성 | |
388 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
389 | + | |
390 | + DataTable param = new DataTable(); | |
391 | + param.setColumnDatas(primaryColumnDatas); | |
392 | + param.setQuery(dataTable.getQuery()); | |
393 | + | |
394 | + //커스텀 쿼리 지정된 PK로 테이블 생성이 가능한지 확인 | |
395 | + int totalOverlapCount = databaseDAO.getCustomQueryPrimaryOverlapCount(param); | |
396 | + | |
397 | + //DB연결 종료 | |
398 | + databaseDAO.dbConnectionClose(); | |
399 | + | |
400 | + //결과 메세지 입력 | |
401 | + if (totalOverlapCount == 0) { | |
402 | + dataTable.getCheckMessage().setSuccess(true); | |
403 | + dataTable.getCheckMessage().setMessage("PK생성 가능 유무 검사 - 지정한 컬럼(" + primaryColumns + ")으로 PrimaryKey 생성이 가능합니다."); | |
404 | + } else { | |
405 | + dataTable.getCheckMessage().setSuccess(false); | |
406 | + dataTable.getCheckMessage().setMessage("PK생성 가능 유무 검사 - 지정한 컬럼(" + primaryColumns + ")으로 PrimaryKey 생성이 불가능합니다.(중복되는 데이터 수 :" + totalOverlapCount + ")"); | |
407 | + } | |
408 | + } | |
409 | + | |
410 | + /** | |
411 | + * @author 김성원 | |
412 | + * @since 2024.01.04 | |
413 | + * | |
414 | + * 커넥션된 데이터베이스의 테이블의 데이터에 대한 데이터 테이블 조회 메서드입니다. | |
415 | + */ | |
416 | + public void setDataTableByDBCollectionQuery (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
417 | + if (dataTable.getColumnDatas() == null || dataTable.getColumnDatas().size() == 0) { | |
418 | + dataTable.getCheckMessage().setMessage("조회할 컬럼정보가 없습니다."); | |
419 | + dataTable.getCheckMessage().setSuccess(false); | |
420 | + logger.info("setDataTableByDBConnectionTable : " + dataTable.getCheckMessage().getMessage()); | |
421 | + return; | |
422 | + } | |
423 | + | |
424 | + //DB연결 확인 | |
425 | + CheckMessage message = dbConnectionCheck(dbCollection); | |
426 | + if (message.isSuccess() == false) { | |
427 | + dataTable.setCheckMessage(message); | |
428 | + logger.info("setDataTableByDBConnectionTable DB연결실패 : " + message.getMessage()); | |
429 | + return; | |
430 | + } | |
431 | + | |
432 | + int tableDataTotalRows = 0; | |
433 | + | |
434 | + List<LinkedHashMap<String, Object>> tableDataMapList = new ArrayList<LinkedHashMap<String, Object>>(); | |
435 | + | |
436 | + //DAO 인스턴스 생성 | |
437 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
438 | + | |
439 | + try { | |
440 | + tableDataMapList = databaseDAO.getDBCollectionQueryDataList(dataTable); | |
441 | + dataTable.setRowData(CommonUtil.rowDataMapToList(tableDataMapList));//테이블 데이터 set | |
442 | + | |
443 | + //테이블 데이터 총 개수 조회 | |
444 | + tableDataTotalRows = databaseDAO.getDBCollectionQueryDataTotalRows(dataTable); | |
445 | + dataTable.setTotalRows(tableDataTotalRows);//테이블 데이터 총 개수 set | |
446 | + }catch(Exception e) { | |
447 | + | |
448 | + }finally { | |
449 | + //DB연결 종료 | |
450 | + databaseDAO.dbConnectionClose(); | |
451 | + } | |
452 | + | |
453 | + | |
454 | + //성공 메세지 입력 | |
455 | + dataTable.getCheckMessage().setSuccess(true); | |
456 | + dataTable.getCheckMessage().setMessage("(총 조회된 행수 " + tableDataTotalRows + "개 / 현재 조회된 데이터 수 " + tableDataMapList.size() + "개)"); | |
457 | + } | |
458 | + | |
459 | + /** | |
460 | + * @author 김성원 | |
461 | + * @since 2024.01.04 | |
462 | + * | |
463 | + * 데이터 셋 목록 Convert List<TableBasicInfo> to List<ColumnData> | |
464 | + */ | |
465 | + /* | |
466 | + public List<ColumnData> tableColumnToColumnData (List<TableBasicInfo> tableBasicList) throws Exception { | |
467 | + List<ColumnData> columnDataList = new ArrayList<ColumnData>(); | |
468 | + for (int i = 0; i < tableBasicList.size(); i++) { | |
469 | + TableBasicInfo tableBasicInfo = tableBasicList.get(i); | |
470 | + ColumnData columnData = new ColumnData(); | |
471 | + columnData.setTableName(tableBasicInfo.getTableName()); | |
472 | + columnData.setColumnNm(tableBasicInfo.getColumnName()); | |
473 | + columnData.setOrginlColumnNm(tableBasicInfo.getColumnName()); | |
474 | + columnData.setDisplyColumnNm(tableBasicInfo.getColumnName()); | |
475 | + columnData.setDbDataType(tableBasicInfo.getDataType()); | |
476 | + columnData.setDataSize(tableBasicInfo.getSize()); | |
477 | + columnData.setPkAt(tableBasicInfo.isPrimary()); | |
478 | + | |
479 | + columnDataList.add(columnData); | |
480 | + } | |
481 | + return columnDataList; | |
482 | + } | |
483 | + */ | |
484 | + | |
485 | + /** | |
486 | + * @author 김성원 | |
487 | + * @since 2022.01.17 | |
488 | + * | |
489 | + * 커넥션된 데이터베이스의 실제 테이블 생성 | |
490 | + */ | |
491 | + public int datasetTableCreate(ConnectionDB dbCollection, DataTable datatable) throws Exception { | |
492 | + | |
493 | + int result = 0; | |
494 | + | |
495 | + //DAO 인스턴스 생성 | |
496 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
497 | + | |
498 | + try { | |
499 | + //테이블 컬럼 목록 조회 | |
500 | + result = databaseDAO.datasetTableCreate(datatable); | |
501 | + }catch (Exception e){ | |
502 | + e.toString(); | |
503 | + }finally { | |
504 | + //DB연결 종료 | |
505 | + databaseDAO.dbConnectionClose(); | |
506 | + } | |
507 | + | |
508 | + return result; | |
509 | + } | |
510 | + | |
511 | + /** | |
512 | + * @author 김성원 | |
513 | + * @since 2022.01.17 | |
514 | + * | |
515 | + * 커넥션된 데이터베이스의 실제 테이블 생성 | |
516 | + */ | |
517 | + public int datasetDefaultTableCreate(ConnectionDB dbCollection, DataTable datatable) throws Exception { | |
518 | + | |
519 | + int result = 0; | |
520 | + | |
521 | + //DAO 인스턴스 생성 | |
522 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
523 | + | |
524 | + try { | |
525 | + //테이블 컬럼 목록 조회 | |
526 | + result = databaseDAO.datasetDefaultTableCreate(datatable); | |
527 | + }catch(Exception e) { | |
528 | + | |
529 | + e.printStackTrace(); | |
530 | + | |
531 | + }finally { | |
532 | + //DB연결 종료 | |
533 | + databaseDAO.dbConnectionClose(); | |
534 | + } | |
535 | + | |
536 | + return result; | |
537 | + } | |
538 | + | |
539 | + /** | |
540 | + * @author 김성원 | |
541 | + * @since 2022.01.17 | |
542 | + * | |
543 | + * 커넥션된 데이터베이스의 실제 테이블 업데이트 | |
544 | + */ | |
545 | + public void datasetDataUpdate(ConnectionDB dbCollection, DataTable datatable) throws Exception { | |
546 | + | |
547 | + //DAO 인스턴스 생성 | |
548 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
549 | + //datatable.getColumnDatas().get(0).isAutoIncrement(); | |
550 | + try { | |
551 | + //테이블 컬럼 목록 조회 | |
552 | + databaseDAO.datasetDataUpdate(datatable); | |
553 | + }catch(Exception e) { | |
554 | + e.printStackTrace(); | |
555 | + throw new Exception(e); | |
556 | + } | |
557 | + finally { | |
558 | + //DB연결 종료 | |
559 | + databaseDAO.dbConnectionClose(); | |
560 | + } | |
561 | + | |
562 | + } | |
563 | + | |
564 | + /** | |
565 | + * @author 김성원 | |
566 | + * @since 2022.01.17 | |
567 | + * | |
568 | + * 커넥션된 데이터베이스의 실제 테이블 이름 중복검사 | |
569 | + */ | |
570 | + public int duplicateCheckTableName(ConnectionDB dbCollection, Map info) throws Exception { | |
571 | + | |
572 | + | |
573 | + int result = 0; | |
574 | + //DAO 인스턴스 생성 | |
575 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
576 | + try { | |
577 | + //테이블 컬럼 목록 조회 | |
578 | + result = databaseDAO.duplicateCheckTableName(info); | |
579 | + }catch (Exception e){ | |
580 | + e.toString(); | |
581 | + }finally { | |
582 | + //DB연결 종료 | |
583 | + databaseDAO.dbConnectionClose(); | |
584 | + } | |
585 | + | |
586 | + return result; | |
587 | + } | |
588 | + | |
589 | + /** | |
590 | + * @author 김성원 | |
591 | + * @since 2022.01.17 | |
592 | + * | |
593 | + * 데이터 셋의 컬럼 정보 목록 조회 SQL에 접근하는 메소드 입니다.(페이징) | |
594 | + */ | |
595 | + public List<LinkedHashMap<String, Object>> getRowData (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
596 | + | |
597 | + List<LinkedHashMap<String, Object>> rowMapData = new ArrayList<LinkedHashMap<String, Object>>(); | |
598 | + | |
599 | + //DAO 인스턴스 생성 | |
600 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
601 | + try { | |
602 | + //테이블 컬럼 목록 조회 | |
603 | + rowMapData = databaseDAO.getRowData(dataTable); | |
604 | + }finally { | |
605 | + //DB연결 종료 | |
606 | + databaseDAO.dbConnectionClose(); | |
607 | + } | |
608 | + | |
609 | + return rowMapData; | |
610 | + } | |
611 | + | |
612 | + /** | |
613 | + * @author 김성원 | |
614 | + * @since 2022.01.17 | |
615 | + * | |
616 | + * 데이터 셋의 컬럼 정보 목록 조회 메소드 입니다.(페이징X) | |
617 | + */ | |
618 | + public List<LinkedHashMap<String, Object>> getRowDataAll (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
619 | + | |
620 | + List<LinkedHashMap<String, Object>> rowMapData = new ArrayList<LinkedHashMap<String, Object>>(); | |
621 | + //DAO 인스턴스 생성 | |
622 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
623 | + | |
624 | + try { | |
625 | + //테이블 컬럼 목록 조회 | |
626 | + rowMapData = databaseDAO.getRowDataAll(dataTable); | |
627 | + }finally { | |
628 | + //DB연결 종료 | |
629 | + databaseDAO.dbConnectionClose(); | |
630 | + } | |
631 | + | |
632 | + return rowMapData; | |
633 | + } | |
634 | + | |
635 | + /** | |
636 | + * @author 김성원 | |
637 | + * @since 2022.01.17 | |
638 | + * | |
639 | + * 데이터 셋의 컬럼 정보 목록 총 갯수 조회 메소드 입니다. | |
640 | + */ | |
641 | + public int getRowDataTotalRows (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
642 | + | |
643 | + int result = 0; | |
644 | + | |
645 | + //DAO 인스턴스 생성 | |
646 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
647 | + | |
648 | + try { | |
649 | + //테이블 컬럼 목록 조회 | |
650 | + result = databaseDAO.getRowDataTotalRows(dataTable); | |
651 | + }finally { | |
652 | + //DB연결 종료 | |
653 | + databaseDAO.dbConnectionClose(); | |
654 | + } | |
655 | + | |
656 | + return result; | |
657 | + } | |
658 | + | |
659 | + /** | |
660 | + * @author 김성원 | |
661 | + * @since 2022.01.17 | |
662 | + * | |
663 | + * 데이터 셋의 비우기 (데이터 셋 내용삭제) | |
664 | + */ | |
665 | + public int emptyDataset (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
666 | + | |
667 | + int result = 0; | |
668 | + //DAO 인스턴스 생성 | |
669 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
670 | + | |
671 | + try { | |
672 | + //테이블 컬럼 목록 조회 | |
673 | + result = databaseDAO.emptyDataset(dataTable); | |
674 | + }finally { | |
675 | + //DB연결 종료 | |
676 | + databaseDAO.dbConnectionClose(); | |
677 | + } | |
678 | + | |
679 | + return result; | |
680 | + } | |
681 | + | |
682 | + /** | |
683 | + * @author 김성원 | |
684 | + * @since 2022.01.17 | |
685 | + * | |
686 | + * 실제 생성된 컬럼 변경 | |
687 | + */ | |
688 | + public int tableColumnChange (DatabaseDAO databaseDAO, TableBasicInfo tableBasicInfo) throws Exception { | |
689 | + | |
690 | + int result = 0; | |
691 | + | |
692 | + //테이블 컬럼 목록 조회 | |
693 | + result = databaseDAO.tableColumnChange(tableBasicInfo); | |
694 | + | |
695 | + return result; | |
696 | + } | |
697 | + | |
698 | + /** | |
699 | + * @author 김성원 | |
700 | + * @since 2022.01.17 | |
701 | + * | |
702 | + * 실제 생성된 테이블 키변경 | |
703 | + */ | |
704 | + public int changePromaryKey (DatabaseDAO databaseDAO, TableBasicInfo tableBasicInfo) throws Exception { | |
705 | + | |
706 | + int result = 0; | |
707 | + | |
708 | + //테이블 컬럼 목록 조회 | |
709 | + result = databaseDAO.changePrimaryKey(tableBasicInfo); | |
710 | + | |
711 | + return result; | |
712 | + } | |
713 | + | |
714 | + /** | |
715 | + * @author 김성원 | |
716 | + * @since 2022.01.17 | |
717 | + * | |
718 | + * 데이터 셋의 ROW 삭제 | |
719 | + */ | |
720 | + public void datasetDataDelete (ConnectionDB dbCollection, DataTable dataTable) throws Exception { | |
721 | + | |
722 | + //DAO 인스턴스 생성 | |
723 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
724 | + | |
725 | + //테이블 컬럼 목록 조회 | |
726 | + databaseDAO.datasetDataDelete(dataTable); | |
727 | + | |
728 | + //DB연결 종료 | |
729 | + databaseDAO.dbConnectionClose(); | |
730 | + } | |
731 | + | |
732 | + /** | |
733 | + * @author 김성원 | |
734 | + * @since 2022.01.17 | |
735 | + * | |
736 | + * AI PK 생성 | |
737 | + */ | |
738 | + public int createAutoIncrement (DatabaseDAO databaseDAO, TableBasicInfo tableBasicInfo) throws Exception { | |
739 | + | |
740 | + int result = 0; | |
741 | + | |
742 | + //테이블 컬럼 목록 조회 | |
743 | + result = databaseDAO.createAutoIncrement(tableBasicInfo); | |
744 | + | |
745 | + return result; | |
746 | + } | |
747 | + | |
748 | + /** | |
749 | + * @author 김성원 | |
750 | + * @since 2022.01.17 | |
751 | + * | |
752 | + * 테이블 메타정보 변경 (comments) | |
753 | + */ | |
754 | + public void updateTableMetaInfo(ConnectionDB dbCollection,DataTable dataTable) throws Exception { | |
755 | + | |
756 | + DatabaseDAO databaseDAO = createDatabaseDAO(dbCollection); | |
757 | + | |
758 | + databaseDAO.updateTableMetaInfo(dataTable); | |
759 | + | |
760 | + } | |
761 | + | |
762 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/util/DataTypeUtil.java
... | ... | @@ -0,0 +1,375 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.util; | |
2 | + | |
3 | +import java.util.*; | |
4 | + | |
5 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.DataType; | |
6 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
7 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
8 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType; | |
9 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
10 | +import com.takensoft.taken_bi_manager.data.vo.ColumnValue; | |
11 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
12 | + | |
13 | +/** | |
14 | + * @author 김성원 | |
15 | + * @since 2024.01.02 | |
16 | + * | |
17 | + * 데이터 타입별로 DB -> JAVA , JAVA -> DB 변경을 위한 인터페이스 입니다. | |
18 | + */ | |
19 | +public class DataTypeUtil { | |
20 | + | |
21 | + | |
22 | + public final static String COLUMN_NAME = "col"; | |
23 | + | |
24 | + /** | |
25 | + * @author 김성원 | |
26 | + * @since 2024.01.09 | |
27 | + * | |
28 | + * 데이터베이스 자료타입을 자바형태로 변환 | |
29 | + */ | |
30 | + public static DataType convertDataTypeDbtoJava (ColumnData column, DatabaseType databaseType ) { | |
31 | + | |
32 | + DataType dataType = null; | |
33 | + | |
34 | + if(databaseType.equals(DatabaseType.MARIADB) || databaseType.equals(DatabaseType.MYSQL)){ | |
35 | + dataType = mariadbDataConvertDBtoJava(column); | |
36 | + }else { | |
37 | + dataType = postgresqlDbDataConvertDBtoJava(column); | |
38 | + } | |
39 | + | |
40 | + return dataType; | |
41 | + } | |
42 | + | |
43 | + /** | |
44 | + * @author 김성원 | |
45 | + * @since 2024.01.09 | |
46 | + * | |
47 | + * 자바 자료형태를 DB 타입으로 변환 | |
48 | + */ | |
49 | + public static DataType convertDataTypeJavatoDB (ColumnData column, DatabaseType databaseType ) { | |
50 | + | |
51 | + | |
52 | + return null; | |
53 | + } | |
54 | + | |
55 | + public static List<ColumnData> convertDataTypeDbtoJavaList(List<ColumnData> ColumnDatas , DatabaseType databaseType){ | |
56 | + | |
57 | + for(ColumnData item : ColumnDatas) { | |
58 | + item.setDataTy(convertDataTypeDbtoJava(item,databaseType)); | |
59 | + } | |
60 | + | |
61 | + | |
62 | + return ColumnDatas; | |
63 | + } | |
64 | + | |
65 | + | |
66 | + // 데이터 테이블 컬럼 DB 자료형으로 변환 | |
67 | + public static void convertDataTableColumMeta(DataTable dataTable) throws Exception { | |
68 | + //데이터가 없을 때 return | |
69 | + if (dataTable.getColumnDatas() == null || dataTable.getColumnDatas().size() == 0) { | |
70 | + dataTable.getCheckMessage().setSuccess(false); | |
71 | + dataTable.getCheckMessage().setMessage("컬럼 정보가 없습니다."); | |
72 | + return; | |
73 | + } else { | |
74 | + | |
75 | + try { | |
76 | + //한 행의 총 varchar size | |
77 | + int varcharTotalSize = 0; | |
78 | + | |
79 | + | |
80 | + // 맥스 사이즈 정하겠음 | |
81 | + //컬럼 정보 세팅 (시작) | |
82 | + for (int cellIndex = 0; cellIndex < dataTable.getColumnDatas().size(); cellIndex++) { | |
83 | + | |
84 | + int maxLength = 50; | |
85 | + | |
86 | + //원본 컬럼명 | |
87 | + String originColumnName = dataTable.getColumnDatas().get(cellIndex).getOrginlColumnNm(); | |
88 | + | |
89 | + //DB에 생성될 컬럼명 set | |
90 | + if (StringUtil.isEmpty(dataTable.getColumnDatas().get(cellIndex).getColumnNm()) == true) { | |
91 | + dataTable.getColumnDatas().get(cellIndex).setColumnNm(COLUMN_NAME + cellIndex); | |
92 | + } | |
93 | + | |
94 | + //컬럼 Index set | |
95 | + dataTable.getColumnDatas().get(cellIndex).setOrdr(cellIndex); | |
96 | + | |
97 | + | |
98 | + dataTable.getColumnDatas().get(cellIndex).setDisplyColumnNm(originColumnName); | |
99 | + | |
100 | + | |
101 | + //열(컬럼)의 데이터 타입 (컬럼의 열 데이터가 없을 때, STRING 타입) | |
102 | + DataType dataType = dataTable.getColumnDatas().get(cellIndex).getDataTy(); | |
103 | + | |
104 | + //컬럼별 데이터의 데이터 타입 목록 (중복 등록은 방지하기 위해 Set으로 설정) | |
105 | + Set<DataType> datatypes = new HashSet<DataType>(); | |
106 | + | |
107 | + //각 컬럼 목록 > 컬럼별 데이터 목록 세팅 | |
108 | + | |
109 | + List<ColumnValue> columnValues = new ArrayList<ColumnValue>(); | |
110 | + for (int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) { | |
111 | + | |
112 | + //cellIndex열 중 rowIndex행 값-value | |
113 | + //String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString(); | |
114 | + Object cellValue = dataTable.getRowData().get(rowIndex).get(cellIndex); | |
115 | + String value = (cellValue != null) ? cellValue.toString() : null; | |
116 | + | |
117 | + if (!StringUtil.isEmpty(value) && value.length() > maxLength) { | |
118 | + maxLength = value.length(); | |
119 | + } | |
120 | + | |
121 | + /* | |
122 | + * 문자열이 비어있거나 | |
123 | + * 문자열이 Null or null or NULL인 경우 실제 null값 세팅 | |
124 | + * */ | |
125 | + if (StringUtil.isEmpty(value) || StringUtil.isNullText(value) == true) { | |
126 | + dataTable.getRowData().get(rowIndex).set(cellIndex, null); | |
127 | + value = null; | |
128 | + } | |
129 | + | |
130 | + //해당 '값'의 '데이터 타입 조회' | |
131 | + DataType type = DataType.getDataType(value); | |
132 | + | |
133 | + //Cell 데이터 값 및 타입 세팅 | |
134 | + /* if(addData == true) { | |
135 | + ColumnValue columnValue = new ColumnValue(); | |
136 | + columnValue.setValue(value);//Cell에 조회된 '데이터 값' 세팅 | |
137 | + columnValue.setDataType(type);//Cell에 조회된 '데이터 타입' 세팅 //dataTable에 Cell 데이터 값 및 타입 세팅 | |
138 | + columnValues.add(columnValue); | |
139 | + }*/ | |
140 | + | |
141 | + | |
142 | + //컬럼별 데이터의 데이터 타입 목록에 데이터 타입 입력 | |
143 | + datatypes.add(type); | |
144 | + | |
145 | + if (rowIndex > 100000) { | |
146 | + | |
147 | + if (dataTable.getRowData().size() > 10000 && rowIndex < dataTable.getRowData().size() - 10000) { | |
148 | + rowIndex = dataTable.getRowData().size() - 10000; | |
149 | + } | |
150 | + // break; | |
151 | + } | |
152 | + } | |
153 | + //각 컬럼 목록 > 컬럼별 데이터 목록 세팅 | |
154 | + //dataTable.getColumnDatas().get(cellIndex).setColumnValues(columnValues); | |
155 | + | |
156 | + //해당 열(컬럼)의 데이터 타입이 지정되지 않았을 때 -> #읽은 컬럼 데이터를 바탕으로 데이터 타입지정# | |
157 | + if (dataType == null) { | |
158 | + dataType = getColumnDataType(datatypes); | |
159 | + dataTable.getColumnDatas().get(cellIndex).setDataTy(dataType); | |
160 | + } | |
161 | + | |
162 | + | |
163 | + | |
164 | + | |
165 | + /*DB데이터 타입 생성*/ | |
166 | + if (dataType == DataType.STRING) {//문자열일 때 => 최대 길이 값 구하기 | |
167 | + ColumnValue columnValue = null; | |
168 | + | |
169 | + //해당 열의 문자열 크기 | |
170 | + int size = maxLength; | |
171 | + | |
172 | + //컬럼의 열 데이터가 존재할 때, 가장 긴 문자열의 글자수 구하기 | |
173 | + /* | |
174 | + * if (columnValues.size() > 0) { //null값 제외한 목록 만들기 List<ColumnValue> | |
175 | + * noneNullColumnValues = columnValues.stream().filter(s -> s.getValue() != | |
176 | + * null).collect(Collectors.toList()); | |
177 | + * | |
178 | + * if (noneNullColumnValues != null && noneNullColumnValues.size() > 0) { //최대 | |
179 | + * 길이 값 구하기 columnValue = noneNullColumnValues.stream().max((s1, s2) -> | |
180 | + * StringUtil.stringLength(s1.getValue()) - | |
181 | + * StringUtil.stringLength(s2.getValue())).get(); //가장 긴 문자열의 글자수 size = | |
182 | + * StringUtil.stringLength(columnValue.getValue()); } } | |
183 | + */ | |
184 | + | |
185 | + //테이블 생성시에 필요한 DB데이터 타입으로 Convert | |
186 | + String dbDataType = DataType.convertDbDataType(dataType, size); | |
187 | + | |
188 | + //DB데이터 타입 입력 | |
189 | + dataTable.getColumnDatas().get(cellIndex).setDbDataType(dbDataType); | |
190 | + //DB데이터 타입이 varchar일 때 => 데이터 타입 크기 입력 | |
191 | + if (dbDataType.equals("varchar")) { | |
192 | + | |
193 | + dataTable.getColumnDatas().get(cellIndex).setDataSize(size);//데이터 타입 크기 입력 | |
194 | + | |
195 | + //varchar 총 사이즈에 추가 | |
196 | + varcharTotalSize += size; | |
197 | + } | |
198 | + } else if (dataTable.getColumnDatas().get(cellIndex).getDataTy() == DataType.DATE) { | |
199 | + | |
200 | + //text -> date형식으로 변경 | |
201 | + for (int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) { | |
202 | + //cellIndex열 중 rowIndex행 값-value | |
203 | + //String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString(); | |
204 | + Object cellValue = dataTable.getRowData().get(rowIndex).get(cellIndex); | |
205 | + String value = (cellValue != null) ? cellValue.toString() : null; | |
206 | + | |
207 | + String dateTextValue = CommonUtil.parseDateText(value); | |
208 | + dataTable.getRowData().get(rowIndex).set(cellIndex, dateTextValue); | |
209 | + } | |
210 | + | |
211 | + dataTable.getColumnDatas().get(cellIndex).setDbDataType(DataType.convertDbDataType(dataType, null)); | |
212 | + dataTable.getColumnDatas().get(cellIndex).setDataSize(100); | |
213 | + } | |
214 | +// } else if (dataTable.getColumnDatas().get(cellIndex).getDataTy() == DataType.TIMESTAMP) { | |
215 | +// | |
216 | +// //text -> date형식으로 변경 | |
217 | +// for (int rowIndex = 0; rowIndex < dataTable.getRowData().size(); rowIndex++) { | |
218 | +// //cellIndex열 중 rowIndex행 값-value | |
219 | +// String value = dataTable.getRowData().get(rowIndex).get(cellIndex).toString(); | |
220 | +// String dateTextValue = CommonUtil.parseDateText(value); | |
221 | +// dataTable.getRowData().get(rowIndex).set(cellIndex, dateTextValue); | |
222 | +// } | |
223 | +// | |
224 | +// dataTable.getColumnDatas().get(cellIndex).setDbDataType(DataType.convertDbDataType(dataType, null)); | |
225 | +// dataTable.getColumnDatas().get(cellIndex).setDataSize(100); | |
226 | +// | |
227 | +// } | |
228 | + else {//'문자열'도 아니고 '날짜'도아닐 때 => DB데이터 타입 입력 | |
229 | + dataTable.getColumnDatas().get(cellIndex).setDbDataType(DataType.convertDbDataType(dataType, null)); | |
230 | + if(maxLength > 20){ | |
231 | + dataTable.getColumnDatas().get(cellIndex).setDataSize(maxLength); | |
232 | + }else{ | |
233 | + dataTable.getColumnDatas().get(cellIndex).setDataSize(20); | |
234 | + } | |
235 | + | |
236 | + } | |
237 | + | |
238 | + }//cell for문 끝 | |
239 | + dataTable.getCheckMessage().setSuccess(true); | |
240 | + dataTable.getCheckMessage().setMessage("컬럼 메타 정보 세팅 완료"); | |
241 | + }catch (Exception e){ | |
242 | + throw new Exception(e); | |
243 | + } | |
244 | + } | |
245 | + | |
246 | + } | |
247 | + | |
248 | + | |
249 | + /** | |
250 | + * @author 김성원 | |
251 | + * @since 2024.01.09 | |
252 | + * | |
253 | + * 마리아 및 myslq 데이터베이스 자료타입을 자바형태로 변환 | |
254 | + */ | |
255 | + private static DataType mariadbDataConvertDBtoJava(ColumnData column) { | |
256 | + | |
257 | + DataType dataType = null; | |
258 | + | |
259 | + // 스트링 타입 변환 | |
260 | + if(Arrays.asList("TEXT", "VARCHAR", "TINYTEXT", "LONGTEXT","ENUM","SET","CHAR","LONGBLOB","BLOB","TINYBLOB","VARBINARY","BINARY","CHAR").contains(column.getDbDataType().toUpperCase().trim())) { | |
261 | + dataType = DataType.STRING; | |
262 | + } | |
263 | + // boolean 타이 변환 | |
264 | + else if(Arrays.asList("BIT").contains(column.getDbDataType().toLowerCase().trim())) { | |
265 | + dataType = DataType.INT; | |
266 | + } | |
267 | + // Integer 타이 변환 | |
268 | + else if(Arrays.asList("TINYINT", "SMALLINT").contains(column.getDbDataType().toUpperCase().trim())) { | |
269 | + dataType = DataType.INT; | |
270 | + } | |
271 | + // Long 타이 변환 | |
272 | + else if(Arrays.asList("MEDIUMINT", "INT","BIGINT").contains(column.getDbDataType().toUpperCase().trim())) { | |
273 | + dataType = DataType.INT; | |
274 | + } | |
275 | + // float 타이 변환 | |
276 | + else if(Arrays.asList("FLOAT").contains(column.getDbDataType().toUpperCase().trim())) { | |
277 | + dataType = DataType.FLOAT; | |
278 | + } | |
279 | + // double 타이 변환 | |
280 | + else if(Arrays.asList("DOUBLE").contains(column.getDbDataType().toUpperCase().trim())) { | |
281 | + dataType = DataType.DOUBLE; | |
282 | + } | |
283 | + // DECIMAL 타이 변환 | |
284 | + else if(Arrays.asList("DECIMAL").contains(column.getDbDataType().toUpperCase().trim())) { | |
285 | + dataType = DataType.DECIMAL; | |
286 | + } | |
287 | + // DATE 타이 변환 | |
288 | + else if(Arrays.asList("DATE").contains(column.getDbDataType().toUpperCase().trim())) { | |
289 | + dataType = DataType.DATE; | |
290 | + } | |
291 | + // TIMESTAMP 타이 변환 | |
292 | + else if(Arrays.asList("DATETIME,TIMESTAMP,TIME").contains(column.getDbDataType().toUpperCase().trim())) { | |
293 | + dataType = DataType.TIMESTAMP; | |
294 | + } | |
295 | + | |
296 | + return dataType; | |
297 | + } | |
298 | + | |
299 | + /** | |
300 | + * @author 김성원 | |
301 | + * @since 2024.01.09 | |
302 | + * | |
303 | + * 마리아 및 myslq 데이터베이스 자료타입을 자바형태로 변환 | |
304 | + */ | |
305 | + private static DataType postgresqlDbDataConvertDBtoJava(ColumnData column) { | |
306 | + | |
307 | + DataType dataType = null; | |
308 | + | |
309 | + // 스트링 타입 변환 | |
310 | + if(Arrays.asList("character varying", "character","text").contains(column.getDbDataType().toLowerCase().trim())) { | |
311 | + dataType = DataType.STRING; | |
312 | + } | |
313 | + // boolean 타이 변환 | |
314 | + else if(Arrays.asList("bit").contains(column.getDbDataType().toLowerCase().trim())) { | |
315 | + dataType = DataType.BOOL; | |
316 | + } | |
317 | + // Integer 타이 변환 | |
318 | + else if(Arrays.asList("integer","smallint","serial").contains(column.getDbDataType().toLowerCase().trim())) { | |
319 | + dataType = DataType.INT; | |
320 | + } | |
321 | + // Long 타이 변환 | |
322 | + else if(Arrays.asList("bigint", "bigserial").contains(column.getDbDataType().toLowerCase().trim())) { | |
323 | + dataType = DataType.LONG; | |
324 | + } | |
325 | + // float 타이 변환 | |
326 | + else if(Arrays.asList("real").contains(column.getDbDataType().toLowerCase().trim())) { | |
327 | + dataType = DataType.FLOAT; | |
328 | + } | |
329 | + // double 타이 변환 | |
330 | + else if(Arrays.asList("double precision","numeric").contains(column.getDbDataType().toLowerCase().trim())) { | |
331 | + dataType = DataType.DOUBLE; | |
332 | + } | |
333 | + // DATE 타이 변환 | |
334 | + else if(Arrays.asList("date","time without time zone").contains(column.getDbDataType().toLowerCase().trim())) { | |
335 | + dataType = DataType.DATE; | |
336 | + } | |
337 | + // TIMESTAMP 타이 변환 | |
338 | + else if(Arrays.asList("time","timestamp","timestamp with time zone","timestamp without time zone", "time with time zone").contains(column.getDbDataType().toLowerCase().trim())) { | |
339 | + dataType = DataType.TIMESTAMP; | |
340 | + }else { | |
341 | + dataType = DataType.STRING; | |
342 | + } | |
343 | + return dataType; | |
344 | + } | |
345 | + | |
346 | + /** | |
347 | + * @author 최정우 | |
348 | + * @since 2019.11.27 | |
349 | + * | |
350 | + * column의 데이터 타입 지정 | |
351 | + */ | |
352 | + public static DataType getColumnDataType (Set<DataType> datatypes) throws Exception { | |
353 | + if (datatypes.contains(DataType.STRING)) { | |
354 | + return DataType.STRING; | |
355 | + } else if (datatypes.contains(DataType.DATE)) { | |
356 | + if (datatypes.contains(DataType.DOUBLE) || datatypes.contains(DataType.LONG)) { | |
357 | + return DataType.STRING; | |
358 | + } else { | |
359 | + return DataType.DATE; | |
360 | + } | |
361 | + } else if (datatypes.contains(DataType.DOUBLE)) { | |
362 | + return DataType.DOUBLE; | |
363 | + } else if (datatypes.contains(DataType.LONG)) { | |
364 | + return DataType.LONG; | |
365 | + } else { | |
366 | + return DataType.STRING; | |
367 | + } | |
368 | + } | |
369 | + | |
370 | + | |
371 | + | |
372 | + | |
373 | + | |
374 | + | |
375 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/ConnectionDB.java
... | ... | @@ -0,0 +1,102 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.vo; | |
2 | + | |
3 | + | |
4 | + | |
5 | + | |
6 | +import com.takensoft.taken_bi_manager.common.util.CryptoUtil; | |
7 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType; | |
8 | + | |
9 | +import lombok.Getter; | |
10 | +import lombok.Setter; | |
11 | + | |
12 | +import java.util.Date; | |
13 | + | |
14 | +@Getter | |
15 | +@Setter | |
16 | +public class ConnectionDB { | |
17 | + | |
18 | + // 커넥션 이름 | |
19 | + private String dbConectId; | |
20 | + | |
21 | + // 커넥션 이름 | |
22 | + private String conectNm; | |
23 | + | |
24 | + // 커넥션 설명 | |
25 | + private String conectDc; | |
26 | + | |
27 | + // 데이터베이스명(데이터 베이스 > 스키마) | |
28 | + private String databaseNm; | |
29 | + | |
30 | + // 스키마명 | |
31 | + private String schemaNm; | |
32 | + | |
33 | + // 데이터 베이스 타입 | |
34 | + private DatabaseType databaseType; | |
35 | + | |
36 | + // IP or URL | |
37 | + private String conectIp; | |
38 | + | |
39 | + // 접속 포트 | |
40 | + private String conectPort; | |
41 | + | |
42 | + // 접속 아이디 | |
43 | + private String userId; | |
44 | + | |
45 | + // 접속 비밀번호 | |
46 | + private String userPassword; | |
47 | + | |
48 | + // 접속 옵션 | |
49 | + private String option; | |
50 | + | |
51 | + // 공통 사용여부 | |
52 | + private boolean useType = true; | |
53 | + | |
54 | + // 사용여부 | |
55 | + private boolean useAt = true; | |
56 | + | |
57 | + // 불러오기 여부 | |
58 | + private boolean loadAt = false; | |
59 | + | |
60 | + | |
61 | + //추가 dataset_post_id | |
62 | + private String dataset_post_id; | |
63 | + | |
64 | + | |
65 | + /** | |
66 | + * 오라클 | |
67 | + * SERVICE: true | |
68 | + * SID: false | |
69 | + * 인지 아닌지 | |
70 | + */ | |
71 | + private boolean isGroupDatabase = false; | |
72 | + | |
73 | + // 생성일 | |
74 | + private String creatDt; | |
75 | + | |
76 | + // 생성자ID | |
77 | + private String creatId; | |
78 | + | |
79 | + // 수정일 | |
80 | + private String updtDt; | |
81 | + | |
82 | + // 수정자 ID | |
83 | + private String updtId; | |
84 | + | |
85 | + private String query; | |
86 | + | |
87 | + private boolean execution; | |
88 | + | |
89 | + // 단방향 암호화 진행 | |
90 | + public void encodingData() { | |
91 | + this.userPassword = CryptoUtil.encryptData(this.userPassword); | |
92 | + } | |
93 | + | |
94 | + // 단방향 복호화 진행 | |
95 | + public void decodingData() { | |
96 | + this.userPassword = CryptoUtil.decryptData(this.userPassword); | |
97 | + } | |
98 | + | |
99 | + | |
100 | + | |
101 | + | |
102 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/DataType.java
... | ... | @@ -0,0 +1,281 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.vo; | |
2 | + | |
3 | +import java.math.BigDecimal; | |
4 | +import java.sql.Timestamp; | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.Date; | |
7 | +import java.util.LinkedHashMap; | |
8 | +import java.util.List; | |
9 | +import java.util.Map; | |
10 | +import java.util.regex.Pattern; | |
11 | + | |
12 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
13 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
14 | + | |
15 | +/** | |
16 | + * @author 김성원 | |
17 | + * @since 2024.01.02 | |
18 | + * | |
19 | + * 데이터 타입을 정의한 상수 Class 입니다. | |
20 | + * 상수명(java데이터타입, 초기값, mysql데이터타입, display데이터타입 | |
21 | + */ | |
22 | + | |
23 | +public enum DataType { | |
24 | + NULL(null, null) | |
25 | + , BYTE(Byte.class, 0) | |
26 | + , BOOL(Boolean.class, false) | |
27 | + , CHAR(Character.class, '\u0000') | |
28 | + , STRING(String.class, "") | |
29 | + , SHORT(Short.class, 0) | |
30 | + , INT(Integer.class, 0) | |
31 | + , DECIMAL(BigDecimal.class,0) | |
32 | + , LONG(Long.class, 0) | |
33 | + , FLOAT(Float.class, 0.0) | |
34 | + , DOUBLE(Double.class, 0.0) | |
35 | + , DATE(Date.class, "") | |
36 | + , DATETIME(Date.class, "") | |
37 | + , TIMESTAMP(Timestamp.class, "") | |
38 | + , ENTER(Character.class,'\n'); | |
39 | + | |
40 | + /** | |
41 | + * enum(열거형데이터)의 생성자 | |
42 | + * 1. 상수에 나열된 parameter와 형태가 똑같이 만들어줘야함. | |
43 | + * 2. 접근제한자는 private로만 다른 접근제한자는 허용하지 않음 | |
44 | + */ | |
45 | + private DataType (Class<?> javaType, Object iniValue) { | |
46 | + this.javaType = javaType; | |
47 | + this.initValue = iniValue; | |
48 | + } | |
49 | + | |
50 | + /** | |
51 | + * java데이터타입 | |
52 | + */ | |
53 | + final private Class<?> javaType; | |
54 | + | |
55 | + /** | |
56 | + * 초기값 | |
57 | + */ | |
58 | + final private Object initValue; | |
59 | + | |
60 | + public Class<?> getJavaType() { | |
61 | + return javaType; | |
62 | + } | |
63 | + public Object getInitValue() { | |
64 | + return initValue; | |
65 | + } | |
66 | + | |
67 | + | |
68 | + /** | |
69 | + * 데이터 타입 검사, DataType 조회 | |
70 | + */ | |
71 | + public static Map<DataType, String> getDataTypeList () { | |
72 | + Map<DataType, String> info = new LinkedHashMap<DataType, String>(); | |
73 | + info.put(STRING, "문자열"); | |
74 | + info.put(LONG, "정수"); | |
75 | + info.put(DOUBLE, "실수"); | |
76 | + info.put(DATE, "날짜"); | |
77 | + info.put(DATETIME,"날짜,시간"); | |
78 | + return info; | |
79 | + } | |
80 | + | |
81 | + /** | |
82 | + * 숫자형 타입 여부 검사 | |
83 | + */ | |
84 | + public static boolean checkTypeNumber (DataType type) { | |
85 | + boolean result = false; | |
86 | + | |
87 | + if(type.equals(INT) || type.equals(LONG) || type.equals(DOUBLE) || type.equals(FLOAT)){ | |
88 | + result = true; | |
89 | + } | |
90 | + return result; | |
91 | + } | |
92 | + | |
93 | + | |
94 | + /** | |
95 | + * 데이터 타입 검사, DataType 조회 | |
96 | + */ | |
97 | + public static List<DataType> getDataTypeArray () { | |
98 | + List<DataType> info = new ArrayList<DataType>(); | |
99 | + info.add(STRING); | |
100 | + info.add(LONG); | |
101 | + info.add(DOUBLE); | |
102 | + info.add(DATE); | |
103 | + info.add(DATETIME); | |
104 | + info.add(BOOL); | |
105 | + return info; | |
106 | + } | |
107 | + | |
108 | + /** | |
109 | + * 데이터 타입 검사, DataType 조회 | |
110 | + */ | |
111 | + public static DataType getDataType (String text) { | |
112 | + /* | |
113 | + * 2021-11-02 김혜민 dataType 전화번호, 날짜 정규식 수정 | |
114 | + * | |
115 | + * | |
116 | + * 전화번호 정규식*/ | |
117 | + String regExp = "^\\d{2,3}-\\d{3,4}-\\d{4}$"; | |
118 | + String regDateTime = "\\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]) (0[1-9]|1[0-9]|2[0-4]):(0[1-9]|[1-5][0-9]):(0[1-9]|[1-5][0-9])"; | |
119 | + String regDate = "\\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])"; | |
120 | + | |
121 | + if(StringUtil.isEmpty(text)) { | |
122 | + return NULL; | |
123 | + } else if(CommonUtil.isLong(text)) { | |
124 | + /* | |
125 | + * 숫자로 변환 가능 하지만 앞에 '0'이 붙어 있으면 문자열로 봄 | |
126 | + * ex) 0102 -> String, 1102 -> Long | |
127 | + */ | |
128 | + if (text.length() > 1 && text.indexOf("0") == 0) { | |
129 | + return STRING; | |
130 | + } else { | |
131 | + return LONG; | |
132 | + } | |
133 | + }else if(CommonUtil.isDouble(text)) { | |
134 | + | |
135 | + return DOUBLE; | |
136 | + | |
137 | + } else if (CommonUtil.isDate(text)) { | |
138 | + /* | |
139 | + * 2021-11-02 김혜민 dataType 전화번호, 날짜 정규식 수정 | |
140 | + * | |
141 | + * | |
142 | + * 전화번호 정규식*/ | |
143 | + boolean expResult = Pattern.matches(regExp, text); | |
144 | + boolean dateTimeResult = Pattern.matches(regDateTime, text); | |
145 | + boolean dateResult = Pattern.matches(regDate, text); | |
146 | + | |
147 | + if(expResult) { | |
148 | + return STRING; | |
149 | + }else if(dateResult) { | |
150 | + return DATE; | |
151 | + }else { | |
152 | + return DATETIME; | |
153 | + } | |
154 | + | |
155 | + } else { | |
156 | + return STRING; | |
157 | + } | |
158 | + } | |
159 | + | |
160 | + /** | |
161 | + * 데이터 타입 검사, dbDataType 조회 | |
162 | + */ | |
163 | + public static String convertDbDataType (DataType datatype, Integer size) { | |
164 | + final int MAX_VARCHAR_SIZE = 765; | |
165 | + | |
166 | + if (datatype == STRING) { | |
167 | + if (size == null || size <= MAX_VARCHAR_SIZE) { | |
168 | + return "varchar"; | |
169 | + } else { | |
170 | + return "text"; | |
171 | + } | |
172 | + } else if (datatype == DATE) { | |
173 | + return "date"; | |
174 | + } else if (datatype == DATETIME){ | |
175 | + return "datetime"; | |
176 | + } else if (datatype == LONG) { | |
177 | + return "bigint"; | |
178 | + } else if (datatype == DOUBLE) { | |
179 | + return "double"; | |
180 | + } else { | |
181 | + return "varchar"; | |
182 | + } | |
183 | + } | |
184 | + | |
185 | + /** | |
186 | + * 데이터 타입 검사, dbDataType -> javaType 조회 | |
187 | + */ | |
188 | + public static DataType convertDataTypeDbtoJava (DataType datatype, Integer size) { | |
189 | + | |
190 | + | |
191 | + return null; | |
192 | + } | |
193 | + | |
194 | + | |
195 | + /** | |
196 | + * 데이터 타입 형태로 값 변경 | |
197 | + */ | |
198 | + public static Object parse(DataType dataType, Object value) { | |
199 | + if (CommonUtil.isNull(value) == true) { | |
200 | + return null; | |
201 | + } | |
202 | + | |
203 | + Class<?> javaType = dataType.getJavaType(); | |
204 | + try { | |
205 | + if (javaType.getSimpleName().equals("Byte")) { | |
206 | + return Byte.parseByte(value.toString()); | |
207 | + } else if (javaType.getSimpleName().equals("Boolean")) { | |
208 | + return Boolean.parseBoolean(value.toString()); | |
209 | + } else if (javaType.getSimpleName().equals("Character")) { | |
210 | + return value.toString().toCharArray(); | |
211 | + } else if (javaType.getSimpleName().equals("String")) { | |
212 | + return value.toString(); | |
213 | + } else if (javaType.getSimpleName().equals("Short")) { | |
214 | + //Short.parseShort(value.toString().replaceAll("[^0-9]","")); | |
215 | + return Short.parseShort(value.toString()); | |
216 | + } else if (javaType.getSimpleName().equals("Integer")) { | |
217 | + //Integer.parseInt(value.toString().replaceAll("[^0-9]","")); | |
218 | + return Integer.parseInt(value.toString()); | |
219 | + } else if (javaType.getSimpleName().equals("Long")) { | |
220 | + //Long.parseLong(value.toString().replaceAll("[^0-9]","")); | |
221 | + return Long.parseLong(value.toString()); | |
222 | + } else if (javaType.getSimpleName().equals("Float")) { | |
223 | + //Float.parseFloat(value.toString().replaceAll("[^0-9]","")); | |
224 | + return Float.parseFloat(value.toString()); | |
225 | + } else if (javaType.getSimpleName().equals("Double")) { | |
226 | + //Double.parseDouble(value.toString().replaceAll("[^0-9]","")); | |
227 | + return Double.parseDouble(value.toString()); | |
228 | + } else { | |
229 | + return value; | |
230 | + } | |
231 | + } catch (Exception e) { | |
232 | + e.printStackTrace(); | |
233 | + return dataType.getInitValue(); | |
234 | + } | |
235 | + } | |
236 | + | |
237 | + /** | |
238 | + * 데이터 타입 형태로 값 변경 | |
239 | + */ | |
240 | + public static boolean parseCheck (DataType dataType, Object value) { | |
241 | + if (CommonUtil.isNull(value) == true) { | |
242 | + return false; | |
243 | + } | |
244 | + | |
245 | + Class<?> javaType = dataType.getJavaType(); | |
246 | + try { | |
247 | + if (javaType.getSimpleName().equals("Byte")) { | |
248 | + Byte.parseByte(value.toString()); | |
249 | + } else if (javaType.getSimpleName().equals("Boolean")) { | |
250 | + Boolean.parseBoolean(value.toString()); | |
251 | + } else if (javaType.getSimpleName().equals("Character")) { | |
252 | + value.toString().toCharArray(); | |
253 | + } else if (javaType.getSimpleName().equals("String")) { | |
254 | + value.toString(); | |
255 | + } else if (javaType.getSimpleName().equals("Short")) { | |
256 | + //Short.parseShort(value.toString().replaceAll("[^0-9]","")); | |
257 | + Short.parseShort(value.toString()); | |
258 | + } else if (javaType.getSimpleName().equals("Integer")) { | |
259 | + //Integer.parseInt(value.toString().replaceAll("[^0-9]","")); | |
260 | + Integer.parseInt(value.toString()); | |
261 | + } else if (javaType.getSimpleName().equals("Long")) { | |
262 | + //Long.parseLong(value.toString().replaceAll("[^0-9]","")); | |
263 | + Long.parseLong(value.toString()); | |
264 | + } else if (javaType.getSimpleName().equals("Float")) { | |
265 | + //Float.parseFloat(value.toString().replaceAll("[^0-9]","")); | |
266 | + Float.parseFloat(value.toString()); | |
267 | + } else if (javaType.getSimpleName().equals("Double")) { | |
268 | + //Double.parseDouble(value.toString().replaceAll("[^0-9]","")); | |
269 | + Double.parseDouble(value.toString()); | |
270 | + } | |
271 | + | |
272 | + return true; | |
273 | + } catch (Exception e) { | |
274 | + //e.printStackTrace(); | |
275 | + return false; | |
276 | + } | |
277 | + } | |
278 | + | |
279 | + | |
280 | +} | |
281 | + |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/TableBasicColumn.java
... | ... | @@ -0,0 +1,56 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +/** | |
7 | + * @author 김성원 | |
8 | + * @since 2024.01.04 | |
9 | + * | |
10 | + * 데이터 베이스 기본 정보를 담는 Class 입니다. | |
11 | + */ | |
12 | +@Getter | |
13 | +@Setter | |
14 | +public class TableBasicColumn implements Cloneable{ | |
15 | + | |
16 | + public TableBasicColumn () {} | |
17 | + | |
18 | + public TableBasicColumn (TableBasicInfo tableBasicInfo) { | |
19 | + this.columnName = tableBasicInfo.getColumnName(); | |
20 | + this.tobeColumnName = tableBasicInfo.getTobeColumnName(); | |
21 | + this.dataType = tableBasicInfo.getDataType(); | |
22 | + this.size = tableBasicInfo.getSize(); | |
23 | + } | |
24 | + | |
25 | + /** | |
26 | + * 컬럼명 | |
27 | + */ | |
28 | + private String columnName; | |
29 | + | |
30 | + /** | |
31 | + * 바뀔 컬럼명 | |
32 | + */ | |
33 | + private String tobeColumnName; | |
34 | + | |
35 | + /** | |
36 | + * 컬럼의 데이터 타입(DB기준) | |
37 | + */ | |
38 | + private String dataType; | |
39 | + | |
40 | + /** | |
41 | + * 컬럼의 데이터 size | |
42 | + */ | |
43 | + private long size; | |
44 | + | |
45 | + /** | |
46 | + * 해당 열의 PK인지 아닌지에 대한 여부 | |
47 | + */ | |
48 | + private boolean isPrimary; | |
49 | + | |
50 | + | |
51 | + | |
52 | + public TableBasicColumn clone() throws CloneNotSupportedException { | |
53 | + return (TableBasicColumn)super.clone(); | |
54 | + } | |
55 | + | |
56 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/db/vo/TableBasicInfo.java
... | ... | @@ -0,0 +1,85 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.db.vo; | |
2 | + | |
3 | +import java.util.ArrayList; | |
4 | +import java.util.List; | |
5 | + | |
6 | +import lombok.Getter; | |
7 | +import lombok.Setter; | |
8 | + | |
9 | +/** | |
10 | + * @author 김성원 | |
11 | + * @since 2024.01.04 | |
12 | + * | |
13 | + * 데이터 베이스 기본 설정 변경시 사용할 class 입니다. | |
14 | + */ | |
15 | +@Getter | |
16 | +@Setter | |
17 | +public class TableBasicInfo { | |
18 | + | |
19 | + public TableBasicInfo () {} | |
20 | + | |
21 | + public TableBasicInfo (String databaseName, String tableName, String columnName) { | |
22 | + this.databaseName = databaseName; | |
23 | + this.tableName = tableName; | |
24 | + this.columnName = columnName; | |
25 | + } | |
26 | + | |
27 | + /** | |
28 | + * 데이터 베이스 명 (스키마명) | |
29 | + */ | |
30 | + private String databaseName; | |
31 | + | |
32 | + /** | |
33 | + * 데이터 베이스 접속 아이디 | |
34 | + */ | |
35 | + private String id; | |
36 | + | |
37 | + /** | |
38 | + * 테이블명 | |
39 | + */ | |
40 | + private String tableName; | |
41 | + | |
42 | + /** | |
43 | + * 컬럼명 | |
44 | + */ | |
45 | + private String columnName; | |
46 | + | |
47 | + /** | |
48 | + * 바뀔 컬럼명 | |
49 | + */ | |
50 | + private String tobeColumnName; | |
51 | + | |
52 | + /** | |
53 | + * 컬럼의 데이터 타입(DB기준) | |
54 | + */ | |
55 | + private String dataType; | |
56 | + | |
57 | + /** | |
58 | + * 컬럼의 데이터 size | |
59 | + */ | |
60 | + private long size; | |
61 | + | |
62 | + /** | |
63 | + * 해당 열의 PK인지 아닌지에 대한 여부 | |
64 | + */ | |
65 | + private boolean isPrimary; | |
66 | + | |
67 | + /** | |
68 | + * PK 리스트 | |
69 | + */ | |
70 | + private List<String> primaryList; | |
71 | + | |
72 | + /** | |
73 | + * PK 리스트 | |
74 | + */ | |
75 | + private String process; | |
76 | + | |
77 | + | |
78 | + /** | |
79 | + * 컬럼의 데이터 목록 | |
80 | + */ | |
81 | + List<TableBasicColumn> tableBasicColumns = new ArrayList<TableBasicColumn>(); | |
82 | + | |
83 | + | |
84 | + | |
85 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/dao/ConnectEhojoPlusDAO.java
... | ... | @@ -0,0 +1,66 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.dao; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.ConnectionEhojoVO; | |
4 | +import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.EhojoPlusParamVO; | |
5 | +import org.apache.ibatis.annotations.Mapper; | |
6 | + | |
7 | +import java.util.*; | |
8 | + | |
9 | +@Mapper | |
10 | +public interface ConnectEhojoPlusDAO { | |
11 | + /** | |
12 | + * @author 박정하 | |
13 | + * @since 2024.12.27 | |
14 | + * | |
15 | + * 차세대 지방재정관리시스템 연결 정보 등록 | |
16 | + */ | |
17 | + public int ehojoPlusInfoInsert(ConnectionEhojoVO connectionEhojoVO) throws Exception; | |
18 | + | |
19 | + /** | |
20 | + * @author 박정하 | |
21 | + * @since 2024.12.27 | |
22 | + * | |
23 | + * 차세대 지방재정관리시스템 헤더 정보 등록 | |
24 | + */ | |
25 | + public int ehojoPlusHeadersInfoInsert(EhojoPlusParamVO ehojoPlusParamVO) throws Exception; | |
26 | + | |
27 | + /** | |
28 | + * @author 박정하 | |
29 | + * @since 2024.12.27 | |
30 | + * | |
31 | + * 차세대 지방재정관리시스템 바디 정보 등록 | |
32 | + */ | |
33 | + public int ehojoPlusBodysInfoInsert(EhojoPlusParamVO ehojoPlusParamVO) throws Exception; | |
34 | + | |
35 | + /** | |
36 | + * @author 박정하 | |
37 | + * @since 2024.12.27 | |
38 | + * | |
39 | + * 차세대 지방재정관리시스템 연결 정보 조회 | |
40 | + */ | |
41 | + public ConnectionEhojoVO selectEhojoPlusInfo(String ehpInfoId) throws Exception; | |
42 | + | |
43 | + /** | |
44 | + * @author 박정하 | |
45 | + * @since 2024.12.27 | |
46 | + * | |
47 | + * 차세대 지방재정관리시스템 연결 정보 삭제 | |
48 | + */ | |
49 | + public int deleteEhojoPlusInfo(String ehpInfoId) throws Exception; | |
50 | + | |
51 | + /** | |
52 | + * @author 박정하 | |
53 | + * @since 2024.12.27 | |
54 | + * | |
55 | + * 차세대 지방재정관리시스템 헤더 정보 삭제 | |
56 | + */ | |
57 | + public int deleteEhojoPlusHeadersInfo(String ehpInfoId) throws Exception; | |
58 | + | |
59 | + /** | |
60 | + * @author 박정하 | |
61 | + * @since 2024.12.27 | |
62 | + * | |
63 | + * 차세대 지방재정관리시스템 바디 정보 삭제 | |
64 | + */ | |
65 | + public int deleteEhojoPlusBodysInfo(String ehpInfoId) throws Exception; | |
66 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/service/ConnectEhojoPlusService.java
... | ... | @@ -0,0 +1,38 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.service; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.ConnectionEhojoVO; | |
4 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
5 | + | |
6 | +public interface ConnectEhojoPlusService { | |
7 | + /** | |
8 | + * @author 하관우 | |
9 | + * @since 2024.12.26 | |
10 | + | |
11 | + * 차세대지방재정 Api 호출 | |
12 | + */ | |
13 | + public CustomeResultMap openFisCal(ConnectionEhojoVO connectionEhojoVO) throws Exception; | |
14 | + | |
15 | + /** | |
16 | + * @author 박정하 | |
17 | + * @since 2024.12.27 | |
18 | + * | |
19 | + * 차세대 지방재정관리시스템 연결 정보 등록 | |
20 | + */ | |
21 | + public int ehojoPlusInfoInsert(ConnectionEhojoVO connectionEhojoVO) throws Exception; | |
22 | + | |
23 | + /** | |
24 | + * @author 박정하 | |
25 | + * @since 2024.12.27 | |
26 | + * | |
27 | + * 차세대 지방재정관리시스템 연결 정보 조회 | |
28 | + */ | |
29 | + public ConnectionEhojoVO selectEhojoPlusInfo(String ehpInfoId) throws Exception; | |
30 | + | |
31 | + /** | |
32 | + * @author 박정하 | |
33 | + * @since 2024.12.27 | |
34 | + * | |
35 | + * 차세대 지방재정관리시스템 연결 정보 삭제 | |
36 | + */ | |
37 | + public int deleteEhojoPlusInfo(String ehpInfoId) throws Exception; | |
38 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/service/impl/ConnectEhojoPlusServiceImpl.java
... | ... | @@ -0,0 +1,89 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.service.impl; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.dao.ConnectEhojoPlusDAO; | |
4 | +import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.service.ConnectEhojoPlusService; | |
5 | +import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.util.OpenFisCal; | |
6 | +import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.ConnectionEhojoVO; | |
7 | +import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.EhojoPlusParamVO; | |
8 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
9 | +import lombok.RequiredArgsConstructor; | |
10 | +import org.springframework.stereotype.Service; | |
11 | +import org.springframework.transaction.annotation.Transactional; | |
12 | + | |
13 | +@Service | |
14 | +@RequiredArgsConstructor | |
15 | +public class ConnectEhojoPlusServiceImpl implements ConnectEhojoPlusService { | |
16 | + private final ConnectEhojoPlusDAO connectEhojoPlusDAO; | |
17 | + | |
18 | + /** | |
19 | + * @author 하관우 | |
20 | + * @since 2024.12.26 | |
21 | + | |
22 | + * 차세대지방재정 Api 호출 | |
23 | + */ | |
24 | + @Override | |
25 | + public CustomeResultMap openFisCal(ConnectionEhojoVO connectionEhojoVO) throws Exception { | |
26 | + //상주시 | |
27 | + connectionEhojoVO.setApiKey("ccef9d3b5e2c1d2d16177898a54e9cc1ff8551b9416c1a8baf33f71db7599cb1"); | |
28 | + connectionEhojoVO.setEncKey("4PTPHNQC8F"); | |
29 | + connectionEhojoVO.setUrl("http://10.60.76.53:26002/"); | |
30 | + OpenFisCal openFisCal = new OpenFisCal(); | |
31 | + return openFisCal.openFisCal(connectionEhojoVO); | |
32 | + } | |
33 | + | |
34 | + /** | |
35 | + * @author 박정하 | |
36 | + * @since 2024.12.27 | |
37 | + * | |
38 | + * 차세대 지방재정관리시스템 연결 정보 등록 | |
39 | + */ | |
40 | + @Override | |
41 | + public int ehojoPlusInfoInsert(ConnectionEhojoVO connectionEhojoVO) throws Exception { | |
42 | + int result = 0; | |
43 | + // 차세대 지방재정관리시스템 연결 정보 등록 | |
44 | + result += connectEhojoPlusDAO.ehojoPlusInfoInsert(connectionEhojoVO); | |
45 | + | |
46 | + for (EhojoPlusParamVO header : connectionEhojoVO.getHeaders()) { | |
47 | + // 차세대 지방재정관리시스템 헤더 정보 등록 | |
48 | + result += connectEhojoPlusDAO.ehojoPlusHeadersInfoInsert(header); | |
49 | + } | |
50 | + for (EhojoPlusParamVO body : connectionEhojoVO.getBodys()) { | |
51 | + // 차세대 지방재정관리시스템 바디 정보 등록 | |
52 | + result += connectEhojoPlusDAO.ehojoPlusBodysInfoInsert(body); | |
53 | + } | |
54 | + | |
55 | + return result; | |
56 | + } | |
57 | + | |
58 | + /** | |
59 | + * @author 박정하 | |
60 | + * @since 2024.12.27 | |
61 | + * | |
62 | + * 차세대 지방재정관리시스템 연결 정보 조회 | |
63 | + */ | |
64 | + public ConnectionEhojoVO selectEhojoPlusInfo(String ehpInfoId) throws Exception { | |
65 | + return connectEhojoPlusDAO.selectEhojoPlusInfo(ehpInfoId); | |
66 | + } | |
67 | + | |
68 | + /** | |
69 | + * @author 박정하 | |
70 | + * @since 2024.12.27 | |
71 | + * | |
72 | + * 차세대 지방재정관리시스템 연결 정보 삭제 | |
73 | + */ | |
74 | + @Override | |
75 | + public int deleteEhojoPlusInfo(String ehpInfoId) throws Exception { | |
76 | + int result = 0; | |
77 | + | |
78 | + // 차세대 지방재정관리시스템 연결 정보 삭제 | |
79 | + result += connectEhojoPlusDAO.deleteEhojoPlusInfo(ehpInfoId); | |
80 | + | |
81 | + // 차세대 지방재정관리시스템 헤더 정보 삭제 | |
82 | + result += connectEhojoPlusDAO.deleteEhojoPlusHeadersInfo(ehpInfoId); | |
83 | + | |
84 | + // 차세대 지방재정관리시스템 바디 정보 삭제 | |
85 | + result += connectEhojoPlusDAO.deleteEhojoPlusBodysInfo(ehpInfoId); | |
86 | + | |
87 | + return result; | |
88 | + } | |
89 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/util/OpenFisCal.java
... | ... | @@ -0,0 +1,204 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.util; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.connection.api.util.DataUtil; | |
4 | +import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.ConnectionEhojoVO; | |
5 | +import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.EhojoPlusParamVO; | |
6 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DataTypeUtil; | |
7 | +import com.takensoft.taken_bi_manager.common.vo.CheckMessage; | |
8 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
9 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
10 | +import net.sf.json.JSONObject; | |
11 | +import org.apache.http.HttpEntity; | |
12 | +import org.apache.http.HttpResponse; | |
13 | +import org.apache.http.client.HttpClient; | |
14 | +import org.apache.http.client.methods.HttpPost; | |
15 | +import org.apache.http.entity.StringEntity; | |
16 | +import org.apache.http.impl.client.HttpClientBuilder; | |
17 | +import org.apache.http.util.EntityUtils; | |
18 | +import com.indigo.util.EncryptionUtils; | |
19 | + | |
20 | +import java.util.ArrayList; | |
21 | +import java.util.HashMap; | |
22 | +import java.util.List; | |
23 | +import java.util.Map; | |
24 | + | |
25 | +public class OpenFisCal { | |
26 | + public CustomeResultMap openFisCal(ConnectionEhojoVO connectionEhojoVO) throws Exception { | |
27 | + // HTTP Client | |
28 | + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); | |
29 | + HttpClient httpClient = httpClientBuilder.build(); | |
30 | + // HTTP Method | |
31 | + String url = connectionEhojoVO.getUrl() + connectionEhojoVO.getTaskCode() + "/openAPI/" + connectionEhojoVO.getTableName(); | |
32 | + HttpPost httpPost = new HttpPost(url); | |
33 | + // HTTP Header | |
34 | + // API 인증키 (외부기관에서 요청 시 필요) | |
35 | + httpPost.setHeader("API_KEY", connectionEhojoVO.getApiKey()); | |
36 | + httpPost.setHeader("Content-Type", "application/json;charset=utf-8"); | |
37 | + // JSON 요청 메시지 | |
38 | + JSONObject jsonReq = new JSONObject(); | |
39 | + // Header | |
40 | + JSONObject header = new JSONObject(); | |
41 | + // body | |
42 | + JSONObject body = new JSONObject(); | |
43 | + | |
44 | + // Header 설정 | |
45 | + for(EhojoPlusParamVO item : connectionEhojoVO.getHeaders()) { | |
46 | + if(item.getKey().equals("tranId")) { | |
47 | + header.put(item.getKey(), EncryptionUtils.makeTxId(connectionEhojoVO.getIfId())); // 트랜잭션 아이디 | |
48 | + } else { | |
49 | + header.put(item.getKey(), item.getValue()); // 다른 값들은 원래 값 그대로 넣기 | |
50 | + } | |
51 | + } | |
52 | + | |
53 | + /********************************************************************** | |
54 | + * 조회 조건 필수 값 설정(인터페이스 정의서 확인 필요) | |
55 | + *********************************************************************/ | |
56 | + // body 설정 | |
57 | + for(EhojoPlusParamVO item : connectionEhojoVO.getBodys()) { | |
58 | + String key = item.getKey(); | |
59 | + body.put(key, item.getValue()); // 다른 값들은 원래 값 그대로 넣기 | |
60 | + } | |
61 | + | |
62 | + /********************************************************************** | |
63 | + * 인터페이스 정의서를 참고하여 추가로 필요한 항목 설정 추가 | |
64 | + * | |
65 | + * 많은 경우 loop 처리하여 페이지 순차 호출 | |
66 | + * | |
67 | + * 조회 조건 필수 값 설정 끝 | |
68 | + *********************************************************************/ | |
69 | + | |
70 | + // JSON 요청 메시지 설정 | |
71 | + jsonReq.put("header", header); | |
72 | + // body 암호화 (외부기관에서 요청 시 필요) | |
73 | + jsonReq.put("body", EncryptionUtils.encryptStringAria(body.toString(), connectionEhojoVO.getEncKey())); | |
74 | + System.out.println("요청 전문" + jsonReq.toString()); | |
75 | + | |
76 | + // Request → Response | |
77 | + httpPost.setEntity(new StringEntity(jsonReq.toString(), "UTF-8")); | |
78 | + HttpResponse httpResponse = httpClient.execute(httpPost); | |
79 | + HttpEntity httpEntity = httpResponse.getEntity(); | |
80 | + | |
81 | + List<Map<String,Object>> dataList = new ArrayList<>(); | |
82 | + CustomeResultMap customeResultMap = new CustomeResultMap(); | |
83 | + | |
84 | + if (httpResponse != null) { | |
85 | + int statusCode = httpResponse.getStatusLine().getStatusCode(); | |
86 | + switch (statusCode) { | |
87 | + case 200: | |
88 | + try { | |
89 | + // 응답 메시지 | |
90 | + String strRes = EntityUtils.toString(httpEntity, "UTF-8"); | |
91 | + // JSON Parsing | |
92 | + JSONObject jsonRes = JSONObject.fromObject(strRes); | |
93 | + | |
94 | + // 응답 코드 확인 | |
95 | + String responseCode = jsonRes.optString("code", ""); | |
96 | + String message = ""; | |
97 | + boolean isSuccess = false; | |
98 | + | |
99 | + switch (responseCode) { | |
100 | + case "0000": | |
101 | + message = "정상"; | |
102 | + isSuccess = true; | |
103 | + // 정상 처리 시에만 body 복호화 | |
104 | + JSONObject resBody = JSONObject.fromObject(EncryptionUtils.decryptStringAria( | |
105 | + jsonRes.getString("body"), | |
106 | + connectionEhojoVO.getEncKey())); | |
107 | + jsonRes.put("body", resBody); | |
108 | + dataList.add(jsonRes); | |
109 | + break; | |
110 | + case "N011": message = "네트워크 오류"; break; | |
111 | + case "D011": message = "DB 접속 오류"; break; | |
112 | + case "D012": message = "DB SQL 오류"; break; | |
113 | + case "F011": message = "파일 IO 오류"; break; | |
114 | + case "G011": message = "대상 시스템 오류"; break; | |
115 | + case "4001": message = "요청 헤더 오류"; break; | |
116 | + case "4002": message = "요청 파라미터 오류"; break; | |
117 | + case "4011": message = "유효하지 않는 API 키"; break; | |
118 | + case "4012": message = "API 사용 권한 없음"; break; | |
119 | + case "4031": message = "일시적인 서비스 제한"; break; | |
120 | + case "4032": message = "기관코드 확인 불가"; break; | |
121 | + case "4041": message = "서비스가 존재하지 않음"; break; | |
122 | + case "4042": message = "인터페이스ID 미 존재"; break; | |
123 | + case "4043": message = "트랜잭션ID 미 존재"; break; | |
124 | + case "4291": message = "정보제공 요청한도 초과"; break; | |
125 | + case "5001": message = "시스템 장애"; break; | |
126 | + case "5002": message = "API 요청 처리 실패"; break; | |
127 | + case "5003": message = "처리시간 초과 에러"; break; | |
128 | + case "5004": message = "알 수 없는 에러"; break; | |
129 | + case "6011": message = "응용프로그램 호출 실패"; break; | |
130 | + case "6012": message = "응용프로그램 타임 아웃"; break; | |
131 | + case "6021": message = "업무 반영 실패"; break; | |
132 | + default: message = "알 수 없는 응답 코드: " + responseCode; | |
133 | + } | |
134 | + | |
135 | + CheckMessage checkMessage = new CheckMessage(isSuccess, message, responseCode); | |
136 | + customeResultMap.setCheckMessage(checkMessage); | |
137 | + | |
138 | + // 로깅 | |
139 | + System.out.println("요청 결과 :: " + jsonRes.toString()); | |
140 | + System.out.println("응답 코드 :: " + responseCode + ", 메시지 :: " + message); | |
141 | + | |
142 | + } catch (Exception e) { | |
143 | + System.err.println("응답 처리 중 오류 발생: " + e.getMessage()); | |
144 | + CheckMessage errorMessage = new CheckMessage(false, "응답 처리 중 오류 발생", "5004"); | |
145 | + customeResultMap.setCheckMessage(errorMessage); | |
146 | + } | |
147 | + break; | |
148 | + | |
149 | + case 400: | |
150 | + customeResultMap.setCheckMessage(new CheckMessage(false, "잘못된 요청", "4002")); | |
151 | + break; | |
152 | + case 401: | |
153 | + customeResultMap.setCheckMessage(new CheckMessage(false, "인증 실패", "4011")); | |
154 | + break; | |
155 | + case 403: | |
156 | + customeResultMap.setCheckMessage(new CheckMessage(false, "접근 권한 없음", "4012")); | |
157 | + break; | |
158 | + case 404: | |
159 | + customeResultMap.setCheckMessage(new CheckMessage(false, "리소스를 찾을 수 없음", "4041")); | |
160 | + break; | |
161 | + case 500: | |
162 | + customeResultMap.setCheckMessage(new CheckMessage(false, "서버 내부 오류", "5001")); | |
163 | + break; | |
164 | + case 503: | |
165 | + customeResultMap.setCheckMessage(new CheckMessage(false, "서비스 일시적 사용 불가", "5002")); | |
166 | + break; | |
167 | + default: | |
168 | + customeResultMap.setCheckMessage(new CheckMessage(false, | |
169 | + "예상치 못한 HTTP 상태 코드: " + statusCode, "5004")); | |
170 | + } | |
171 | + } else { | |
172 | + customeResultMap.setCheckMessage(new CheckMessage(false, "HTTP 응답이 null입니다", "5004")); | |
173 | + } | |
174 | + | |
175 | + int max = 0; | |
176 | + int indx = 0; | |
177 | + | |
178 | + // 최대 길이의 키값을 가진 객체 구하기 | |
179 | + for(int i = 0 ; i < dataList.size() ; i++){ | |
180 | + if(dataList.get(i).keySet().size() > max) { | |
181 | + max = dataList.get(i).keySet().size(); | |
182 | + indx = i; | |
183 | + } | |
184 | + } | |
185 | + // 빈정보 공백으로 채우기 | |
186 | + for(Map<String, Object> item : dataList ) { | |
187 | + if(max != item.size()) { | |
188 | + for (Map.Entry<String, Object> entry : dataList.get(indx).entrySet()) | |
189 | + { | |
190 | + if(item.get(entry.getKey()) == null) { | |
191 | + item.put(entry.getKey(),""); | |
192 | + } | |
193 | + } | |
194 | + } | |
195 | + } | |
196 | + DataTable dataTable = DataUtil.setMaptoDataTable(dataList); | |
197 | + DataUtil.setColumnMetaData(dataTable, false); | |
198 | + DataTypeUtil.convertDataTableColumMeta(dataTable); | |
199 | + HashMap<String, Object> dataMap = new HashMap<>(); | |
200 | + dataMap.put("dataTable", dataTable); // 또는 적절한 키 이름 사용 | |
201 | + customeResultMap.setResultData(dataMap); | |
202 | + return customeResultMap; | |
203 | + } | |
204 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/vo/ConnectionEhojoVO.java
... | ... | @@ -0,0 +1,39 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.jobs.vo.item.JobReadConItm; | |
4 | +import lombok.Getter; | |
5 | +import lombok.Setter; | |
6 | + | |
7 | +import java.io.Serializable; | |
8 | +import java.util.*; | |
9 | + | |
10 | +@Getter | |
11 | +@Setter | |
12 | +public class ConnectionEhojoVO extends JobReadConItm implements Serializable { | |
13 | + // 차세대 지방재정관리시스템 연결 정보 아이디 | |
14 | + private String ehpInfoId; | |
15 | + | |
16 | + // front에서 설정하는 정보 | |
17 | + // 인터페이스 ID | |
18 | + private String ifId; | |
19 | + // 송신기관 코드 | |
20 | + private String lafCode; | |
21 | + // 업무구분 코드 | |
22 | + private String taskCode; | |
23 | + // 테이블 명 | |
24 | + private String tableName; | |
25 | + | |
26 | + // back에서 설정하는 정보 | |
27 | + // 호출 url 설정 | |
28 | + private String url; | |
29 | + // apiKey 설정 | |
30 | + private String apiKey; | |
31 | + // 암복호화 key 설정 | |
32 | + private String encKey; | |
33 | + | |
34 | + // 헤더 키, 값 목록 | |
35 | + private List<EhojoPlusParamVO> headers = new ArrayList<>(); | |
36 | + | |
37 | + // 바디 키, 값 목록 | |
38 | + private List<EhojoPlusParamVO> bodys = new ArrayList<>(); | |
39 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/vo/EhojoPlusParamVO.java
... | ... | @@ -0,0 +1,20 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +@Getter | |
7 | +@Setter | |
8 | +public class EhojoPlusParamVO { | |
9 | + // 차세대 지방재정관리시스템 연결 정보 아이디 | |
10 | + private String ehpInfoId; | |
11 | + | |
12 | + // 인덱스 | |
13 | + private int index; | |
14 | + // 키 | |
15 | + private String key; | |
16 | + // 값 | |
17 | + private String value; | |
18 | + // 필수 여부 (프론트에서 사용) | |
19 | + private String required; | |
20 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/ehojoPlus/web/ConnectEhojoPlusController.java
... | ... | @@ -0,0 +1,68 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.ehojoPlus.web; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.service.ConnectEhojoPlusService; | |
4 | +import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.ConnectionEhojoVO; | |
5 | +import lombok.RequiredArgsConstructor; | |
6 | +import org.springframework.stereotype.Controller; | |
7 | +import org.springframework.web.bind.annotation.RequestBody; | |
8 | +import org.springframework.web.bind.annotation.RequestMapping; | |
9 | +import org.springframework.web.bind.annotation.RequestMethod; | |
10 | +import org.springframework.web.servlet.ModelAndView; | |
11 | + | |
12 | +@Controller | |
13 | +@RequiredArgsConstructor | |
14 | +public class ConnectEhojoPlusController { | |
15 | + private final ConnectEhojoPlusService connectEhojoPlusService; | |
16 | + | |
17 | + /** | |
18 | + * @author 하관우 | |
19 | + * @since 2024.12.26 | |
20 | + | |
21 | + * 차세대지방재정 Api 호출 | |
22 | + */ | |
23 | + @RequestMapping(value ="/openfiscal.json", method = RequestMethod.POST) | |
24 | + public ModelAndView openFisCal(@RequestBody ConnectionEhojoVO connectionEhojoVO) throws Exception{ | |
25 | + ModelAndView mav = new ModelAndView("jsonView"); | |
26 | + mav.addObject("customeResultMap", connectEhojoPlusService.openFisCal(connectionEhojoVO)); | |
27 | + return mav; | |
28 | + } | |
29 | + | |
30 | + /** | |
31 | + * @author 박정하 | |
32 | + * @since 2024.12.27 | |
33 | + * | |
34 | + * 차세대 지방재정관리시스템 연결 정보 등록 | |
35 | + */ | |
36 | + @RequestMapping(value ="/ehojoConnectionInfoInsert.json", method = RequestMethod.POST) | |
37 | + public ModelAndView ehojoPlusInfoInsert(@RequestBody ConnectionEhojoVO connectionEhojoVO) throws Exception{ | |
38 | + ModelAndView mav = new ModelAndView("jsonView"); | |
39 | + mav.addObject("dataTableResult", connectEhojoPlusService.ehojoPlusInfoInsert(connectionEhojoVO)); | |
40 | + return mav; | |
41 | + } | |
42 | + | |
43 | + /** | |
44 | + * @author 박정하 | |
45 | + * @since 2024.12.27 | |
46 | + * | |
47 | + * 차세대 지방재정관리시스템 연결 정보 조회 | |
48 | + */ | |
49 | + @RequestMapping(value ="/ehojoConnectionInfoSelect.json", method = RequestMethod.POST) | |
50 | + public ModelAndView selectEhojoPlusInfo(@RequestBody ConnectionEhojoVO connectionEhojoVO) throws Exception{ | |
51 | + ModelAndView mav = new ModelAndView("jsonView"); | |
52 | + mav.addObject("dataTableResult", connectEhojoPlusService.selectEhojoPlusInfo(connectionEhojoVO.getEhpInfoId())); | |
53 | + return mav; | |
54 | + } | |
55 | + | |
56 | + /** | |
57 | + * @author 박정하 | |
58 | + * @since 2024.12.27 | |
59 | + * | |
60 | + * 차세대 지방재정관리시스템 연결 정보 삭제 | |
61 | + */ | |
62 | + @RequestMapping(value ="/ehojoConnectionInfoDelete.json", method = RequestMethod.POST) | |
63 | + public ModelAndView ehojoPlusInfoDelete(@RequestBody ConnectionEhojoVO connectionEhojoVO) throws Exception{ | |
64 | + ModelAndView mav = new ModelAndView("jsonView"); | |
65 | + mav.addObject("dataTableResult", connectEhojoPlusService.deleteEhojoPlusInfo(connectionEhojoVO.getEhpInfoId())); | |
66 | + return mav; | |
67 | + } | |
68 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/connection/util/DataTableCreate.java
... | ... | @@ -0,0 +1,124 @@ |
1 | +package com.takensoft.taken_bi_manager.common.connection.util; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DataTypeUtil; | |
4 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
5 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
6 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
7 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
8 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode; | |
9 | +import com.takensoft.taken_bi_manager.data.dao.DatasetDAO; | |
10 | +import com.takensoft.taken_bi_manager.data.service.DataService; | |
11 | +import com.takensoft.taken_bi_manager.data.service.DatasetService; | |
12 | +import com.takensoft.taken_bi_manager.data.util.DataTableConvert; | |
13 | +import com.takensoft.taken_bi_manager.data.vo.*; | |
14 | +import com.takensoft.taken_bi_manager.jobs.util.JobUtil; | |
15 | +import com.takensoft.taken_bi_manager.jobs.vo.JobItm; | |
16 | +import org.springframework.beans.factory.annotation.Autowired; | |
17 | +import org.springframework.stereotype.Component; | |
18 | +import org.springframework.transaction.annotation.Transactional; | |
19 | + | |
20 | +import java.util.List; | |
21 | + | |
22 | +@Component | |
23 | +public class DataTableCreate { | |
24 | + | |
25 | + @Autowired | |
26 | + private DataService dataService; | |
27 | + | |
28 | + @Autowired | |
29 | + private DatasetService datasetService; | |
30 | + | |
31 | + @Autowired | |
32 | + private DatasetDAO datasetDAO; | |
33 | + | |
34 | + /** | |
35 | + * @author 김성원 | |
36 | + * @since 2024.02.15 | |
37 | + * <p> | |
38 | + * 데이터 테이블 생성 Background 실행 | |
39 | + */ | |
40 | + @Transactional(rollbackFor = Exception.class) | |
41 | + public void dataTableCreateTable(DatasetPost datasetPost, Dataset tempDataset, ConnectionDB connectionDB, JobItm itm, String member) throws Exception { | |
42 | + | |
43 | + String datasetPostId = datasetPost.getDataset_post_id(); | |
44 | + try { | |
45 | + DataTable resultTable; | |
46 | + if(itm.getDataTable().getQuery().equals("") || itm.getDataTable().getQuery() == null){ | |
47 | + resultTable = (DataTable)itm.getDataTable().clone(); | |
48 | + } else { | |
49 | + List<Boolean> keyList = DataTableConvert.pkList(itm.getDataTable()); | |
50 | + resultTable = JobUtil.dbConnectionExec(itm); | |
51 | + DataTableConvert.setPkist(keyList,resultTable); | |
52 | + } | |
53 | + | |
54 | + resultTable.setDatasetPostId(datasetPostId); | |
55 | + resultTable.setDatabaseNm(connectionDB.getDatabaseNm()); | |
56 | + DataTypeUtil.convertDataTableColumMeta(resultTable); | |
57 | + resultTable.setTableNm(tempDataset.getTableNm().toLowerCase()); | |
58 | + resultTable.setTableNmKr(tempDataset.getTableNmKr()); | |
59 | + resultTable.setDatasetSj(datasetPost.getPost_sj()); | |
60 | + | |
61 | + for(ColumnData data : resultTable.getColumnDatas()) { | |
62 | + if(StringUtil.isEmpty(data.getColumnNm())){ | |
63 | + data.setColumnNm(data.getOrginlColumnNm()); | |
64 | + } | |
65 | + } | |
66 | + | |
67 | + connectionDB.setLoadAt(true); | |
68 | + | |
69 | + // 테이블 생성 | |
70 | + dataService.datasetTableCreate(resultTable, SystemCode.DatasetType.RAW, connectionDB); | |
71 | + | |
72 | + String connectionId = ""; | |
73 | + | |
74 | + // 커넥션 아이디 없을때 | |
75 | + if(StringUtil.isEmpty(connectionDB.getDbConectId())){ | |
76 | + CustomeResultMap resultMap = dataService.conflictInsertDbConnection(connectionDB); | |
77 | + connectionId = resultMap.getResultData().get("dbConectId").toString(); | |
78 | + }else{ | |
79 | + connectionId = connectionDB.getDbConectId(); | |
80 | + } | |
81 | + | |
82 | + // 데이터셋 등록 | |
83 | + Dataset dataset = new Dataset(); | |
84 | + dataset.setDbConectId(connectionDB.getDbConectId()); | |
85 | + dataset.setDatasetId(resultTable.getDatasetId());//datasetTableCreate 생성시 datasetId를 받아옴 | |
86 | + dataset.setTableNm(resultTable.getTableNm());//datasetTableCreate 생성시 DB에 생성된 Table명을 받아옴 | |
87 | + dataset.setCreatTableAt(true); | |
88 | + dataset.setDatasetSj(datasetPost.getPost_sj());//데이터 셋 명(데이터명) | |
89 | + dataset.setTableNmKr(resultTable.getTableNmKr()); | |
90 | + dataset.setDatasetPostId(datasetPostId); | |
91 | + // dataset.setDatasetDataType(DataUtil.getDatasetDataType(tempTable.getColumnDatas()));//해당 데이터 셋의 데이터 타입 | |
92 | + datasetService.conflictInsertDataset(dataset); | |
93 | + | |
94 | + //컬럼 정보 등록 (컬럼이 존재할 때만 등록 가능) | |
95 | + for (int j = 0; j < resultTable.getColumnDatas().size(); j++) { | |
96 | + ColumnData columnData = resultTable.getColumnDatas().get(j); | |
97 | + columnData.setDatasetId(dataset.getDatasetId()); | |
98 | + datasetService.conflictInsertCoulmnInfo((Column) columnData); | |
99 | + } | |
100 | + | |
101 | + /*데이터 등록*/ | |
102 | + dataService.datasetDataUpdate(resultTable,connectionDB, "user"); | |
103 | + | |
104 | + /*업데이트 로그 생성*/ | |
105 | + //데이터 업데이트 로그 저장 처리 | |
106 | + DatasetPostLog datasetPostLog = new DatasetPostLog(datasetPostId, member); | |
107 | + datasetPostLog.setSuccess("C"); | |
108 | + datasetPostLog.setCRUD(resultTable.getTotalRows(), 0, 0); | |
109 | + datasetPostLog.setLog_sttus("C"); | |
110 | + | |
111 | + datasetDAO.insertDatasetPostLog(datasetPostLog); | |
112 | + | |
113 | + }catch (Exception e){ | |
114 | + /*업데이트 로그 생성*/ | |
115 | + //데이터 업데이트 로그 저장 처리 | |
116 | + DatasetPostLog datasetPostLog = new DatasetPostLog(datasetPostId,member); | |
117 | + datasetPostLog.setError(e.toString(),"C"); | |
118 | + datasetPostLog.setCRUD(0, 0, 0); | |
119 | + datasetPostLog.setLog_sttus("E"); | |
120 | + datasetDAO.insertDatasetPostLog(datasetPostLog); | |
121 | + throw new Exception(e); | |
122 | + } | |
123 | + } | |
124 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/dao/FileDAO.java
... | ... | @@ -0,0 +1,73 @@ |
1 | +package com.takensoft.taken_bi_manager.common.file.dao; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.file.vo.CmmnFile; | |
4 | +import com.takensoft.taken_bi_manager.common.file.vo.FileManage; | |
5 | +import org.apache.ibatis.annotations.Mapper; | |
6 | + | |
7 | +import java.util.HashMap; | |
8 | +import java.util.List; | |
9 | + | |
10 | +@Mapper | |
11 | +public interface FileDAO { | |
12 | + /** | |
13 | + * @author 방선주 | |
14 | + * @since 2024.04.22 | |
15 | + * | |
16 | + * file manager 등록 | |
17 | + */ | |
18 | + void fileManagerInsert(FileManage fileManage); | |
19 | + /** | |
20 | + * @author 방선주 | |
21 | + * @since 2024.04.22 | |
22 | + * | |
23 | + * cmmn_file 등록 | |
24 | + */ | |
25 | + void fileInsert(CmmnFile fileInfo); | |
26 | + /** | |
27 | + * @author 방선주 | |
28 | + * @since 2024.04.22 | |
29 | + * | |
30 | + * 이미지 경로 cmmnfile에서 가져오기 | |
31 | + */ | |
32 | + CmmnFile cmmnfileSelect(String fileManagerId); | |
33 | + /** | |
34 | + * @author 방선주 | |
35 | + * @since 2024.04.22 | |
36 | + * | |
37 | + * cmmnfile에서 이미지 경로 삭제 | |
38 | + */ | |
39 | + void cmmnfileDelete(String fileManagerId); | |
40 | + /** | |
41 | + * @author 방선주 | |
42 | + * @since 2024.04.22 | |
43 | + * | |
44 | + * fileManager에서 이미지 경로 삭제 | |
45 | + */ | |
46 | + void fileManagerDelete(String fileManagerId); | |
47 | + | |
48 | + /** | |
49 | + * @author 박민혁 | |
50 | + * @since 2024.04.24 | |
51 | + * | |
52 | + * 이미지 경로 cmmnfile에서 파일 여러개 가져오기 | |
53 | + */ | |
54 | + public List<CmmnFile> cmmnfilesSelect(String fileManagerId); | |
55 | + | |
56 | + /** | |
57 | + * @author 박민혁 | |
58 | + * @since 2024.04.24 | |
59 | + * | |
60 | + * 파일 정보 삭제 | |
61 | + */ | |
62 | + public int deleteCmmnFileToDataSetPost(String fileManagerId); | |
63 | + | |
64 | + /** | |
65 | + * @author 박민혁 | |
66 | + * @since 2024.04.24 | |
67 | + * | |
68 | + * 파일 매니저 삭제 | |
69 | + */ | |
70 | + public int deleteFileManagerToDataSetPost(String fileManagerId); | |
71 | + | |
72 | + | |
73 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/handler/Sheet2ListHandler.java
... | ... | @@ -0,0 +1,242 @@ |
1 | +package com.takensoft.taken_bi_manager.common.file.handler; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
4 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
5 | +import org.xml.sax.SAXException; | |
6 | + | |
7 | +import java.util.ArrayList; | |
8 | +import java.util.HashMap; | |
9 | +import java.util.List; | |
10 | +import java.util.Map; | |
11 | + | |
12 | + | |
13 | +public class Sheet2ListHandler implements SheetHandler.SheetContentsHandler2 { | |
14 | +//public class Sheet2ListHandler implements SheetHandler{ | |
15 | + //collection 객체 | |
16 | + private List<List<Object>> rows; | |
17 | + //collection에 추가될 객체 startRow에서 초기화함. | |
18 | + private List<Object> row; | |
19 | + | |
20 | + //collection 내 객체를 String[]로 잡았기 때문에 배열의 길이를 생서시 받도록 설계 | |
21 | +// private int columnCnt; | |
22 | + private int currentRowIndex = 0; | |
23 | + | |
24 | + private int maxCellLength = 0; | |
25 | + | |
26 | + /* 정우 추가 */ | |
27 | + | |
28 | + //생략된 row Index's | |
29 | + private List<Integer> skipRowIndexs = new ArrayList<Integer>(); | |
30 | + | |
31 | + //데이터 영역 | |
32 | + private int firstRow = 0; | |
33 | + private int firstColumn = 0; | |
34 | + private int lastRow = 0; | |
35 | + private int lastColumn = 0; | |
36 | + | |
37 | + private List<Map<String, Integer>> mergeCellInfoList; | |
38 | + | |
39 | + //행에 열데이터가 1개라도 존재하는지 체크 (row 시작할 때, false로 초기화 시켜야됨) | |
40 | + boolean isRowDataExist = false; | |
41 | + private List<Integer> rowDataNoneExistIndexs = new ArrayList<Integer>(); | |
42 | + | |
43 | + // 하석형 추가 | |
44 | + private int limit = 0; // 미리보기 전용 limit | |
45 | + private int rowCount = 0; // 처리한 row의 수를 카운팅 | |
46 | + | |
47 | + /* 정우 추가 */ | |
48 | + //외부 collection과 배열 size를 받기 위해 추가한 부분 | |
49 | + public Sheet2ListHandler(List<List<Object>> rows/*, int columnsCnt*/, int limit) { | |
50 | + this.rows = rows; | |
51 | + this.limit = limit; | |
52 | + } | |
53 | + | |
54 | + //Row의 시작 부분에서 발생하는 이벤트를 처리하는 method | |
55 | + public void startRow(String currentRowIndex) throws SAXException { | |
56 | + if(this.rowCount >= this.limit) { | |
57 | +// throw new LimitReachedException("Limit reached"); | |
58 | + throw new SAXException("limit"); | |
59 | +// return; | |
60 | + } | |
61 | + this.currentRowIndex = CommonUtil.parseInt(currentRowIndex); | |
62 | + | |
63 | + //처음 데이터 읽기 시작한 엑셀의 행 Index (0부터 시작) | |
64 | + this.row = new ArrayList<Object>(); | |
65 | + //*행에 열데이터가 1개라도 존재하는지 체크값 '초기화'* | |
66 | + this.isRowDataExist = false; | |
67 | + } | |
68 | + | |
69 | + //Row의 끝에서 발생하는 이벤트를 처리하는 method | |
70 | + public void endRow() { | |
71 | + //최대 열 개수 '최신화' | |
72 | + if (this.maxCellLength < row.size()) { | |
73 | + this.maxCellLength = row.size(); | |
74 | + } | |
75 | + //row데이터 추가 | |
76 | + this.rows.add(this.row); | |
77 | + | |
78 | + //행에 열데이터가 1개라도 존재하지 않을 때 -> Index 추가 | |
79 | + if (this.isRowDataExist == false) { | |
80 | + rowDataNoneExistIndexs.add((this.rows.size() - 1)); | |
81 | + } | |
82 | + this.rowCount++; // 처리한 row의 수를 카운팅 | |
83 | + } | |
84 | + | |
85 | + public void cellDataAdd(String value) { | |
86 | + //cell 이벤트 발생 시 해당 cell의 주소와 값을 받아옴. | |
87 | + //입맛에 맞게 처리하면 됨. | |
88 | + | |
89 | + if (StringUtil.isEmpty(value) == true) { | |
90 | + this.row.add(null); | |
91 | + } else { | |
92 | + this.row.add(value); | |
93 | + this.isRowDataExist = true; | |
94 | + } | |
95 | + } | |
96 | + | |
97 | + /* 정우 추가 */ | |
98 | + public void findMerge () { | |
99 | + this.mergeCellInfoList = new ArrayList<Map<String, Integer>>(); | |
100 | + } | |
101 | + | |
102 | + public void addMergeInfo (int firstRow, int firstColumn, int lastRow, int lastColumn) { | |
103 | + Map<String, Integer> info = new HashMap<String, Integer>(); | |
104 | + info.put("firstRow", firstRow); | |
105 | + info.put("firstColumn", firstColumn); | |
106 | + info.put("lastRow", lastRow); | |
107 | + info.put("lastColumn", lastColumn); | |
108 | + | |
109 | + this.mergeCellInfoList.add(info); | |
110 | + } | |
111 | + /* 정우 추가 */ | |
112 | + | |
113 | + public String overriddenFormat(String cellRef, int formatIndex, String formatString, String value) { | |
114 | + if(formatString != null && (formatString.equals("reserved-0x1f")||formatString.equals("m/d/yy")||formatString.equals("yy/mm/dd") | |
115 | + ||formatString.equals("[$-F800]dddd\\,\\ mmmm\\ dd\\,\\ yyyy"))) { | |
116 | + return "yyyy-mm-dd;@"; | |
117 | + } | |
118 | + | |
119 | + return null; | |
120 | + } | |
121 | + | |
122 | + public void headerFooter(String paramString1, boolean paramBoolean, String paramString2) { | |
123 | + | |
124 | + } | |
125 | + | |
126 | + /* 정우 추가 */ | |
127 | + public void endEvent () { | |
128 | + | |
129 | + if (mergeCellInfoList != null && mergeCellInfoList.size() > 0) { | |
130 | + for (int i = 0; i < mergeCellInfoList.size(); i++) { | |
131 | + int firstRow = mergeCellInfoList.get(i).get("firstRow") - this.firstRow; | |
132 | + int firstColumn = mergeCellInfoList.get(i).get("firstColumn") - this.firstColumn; | |
133 | + int lastRow = mergeCellInfoList.get(i).get("lastRow") - this.firstRow; | |
134 | + int lastColumn = mergeCellInfoList.get(i).get("lastColumn") - this.firstColumn; | |
135 | + | |
136 | + String value = (String) rows.get(firstRow).get(firstColumn); | |
137 | + | |
138 | + for (int j = firstRow; j <= lastRow; j++) { | |
139 | + for (int z = firstColumn; z <= lastColumn; z++) { | |
140 | + rows.get(j).set(z, value); | |
141 | + } | |
142 | + } | |
143 | + } | |
144 | + } | |
145 | + | |
146 | + for (int removeCount = 0; removeCount < this.rowDataNoneExistIndexs.size(); removeCount++) { | |
147 | + int removeIndex = this.rowDataNoneExistIndexs.get(removeCount); | |
148 | + if (removeIndex > -1) { | |
149 | + rows.remove(removeIndex - removeCount); | |
150 | + } | |
151 | + } | |
152 | + } | |
153 | + | |
154 | + | |
155 | + /* 정우 추가 */ | |
156 | + public List<List<Object>> getRows() { | |
157 | + return rows; | |
158 | + } | |
159 | + | |
160 | + public void setRows(List<List<Object>> rows) { | |
161 | + this.rows = rows; | |
162 | + } | |
163 | + | |
164 | + public List<Object> getRow() { | |
165 | + return row; | |
166 | + } | |
167 | + | |
168 | + public void setRow(List<Object> row) { | |
169 | + this.row = row; | |
170 | + } | |
171 | + | |
172 | + public int getMaxCellLength() { | |
173 | + return maxCellLength; | |
174 | + } | |
175 | + | |
176 | + public void setMaxCellLength(int maxCellLength) { | |
177 | + this.maxCellLength = maxCellLength; | |
178 | + } | |
179 | + | |
180 | + public List<Integer> getSkipRowIndexs() { | |
181 | + return skipRowIndexs; | |
182 | + } | |
183 | + | |
184 | + public void setSkipRowIndexs(List<Integer> skipRowIndexs) { | |
185 | + this.skipRowIndexs = skipRowIndexs; | |
186 | + } | |
187 | + | |
188 | + public int getFirstRow() { | |
189 | + return firstRow; | |
190 | + } | |
191 | + | |
192 | + public void setFirstRow(int firstRow) { | |
193 | + this.firstRow = firstRow; | |
194 | + } | |
195 | + | |
196 | + public int getFirstColumn() { | |
197 | + return firstColumn; | |
198 | + } | |
199 | + | |
200 | + public void setFirstColumn(int firstColumn) { | |
201 | + this.firstColumn = firstColumn; | |
202 | + } | |
203 | + | |
204 | + public int getLastRow() { | |
205 | + return lastRow; | |
206 | + } | |
207 | + | |
208 | + public void setLastRow(int lastRow) { | |
209 | + this.lastRow = lastRow; | |
210 | + } | |
211 | + | |
212 | + public int getLastColumn() { | |
213 | + return lastColumn; | |
214 | + } | |
215 | + | |
216 | + public void setLastColumn(int lastColumn) { | |
217 | + this.lastColumn = lastColumn; | |
218 | + } | |
219 | + | |
220 | + public List<Map<String, Integer>> getMergeCellInfoList() { | |
221 | + return mergeCellInfoList; | |
222 | + } | |
223 | + | |
224 | + public void setMergeCellInfoList(List<Map<String, Integer>> mergeCellInfoList) { | |
225 | + this.mergeCellInfoList = mergeCellInfoList; | |
226 | + } | |
227 | + | |
228 | + public List<Integer> getRowDataNoneExistIndexs() { | |
229 | + return rowDataNoneExistIndexs; | |
230 | + } | |
231 | + | |
232 | + public void setRowDataNoneExistIndexs(List<Integer> rowDataNoneExistIndexs) { | |
233 | + this.rowDataNoneExistIndexs = rowDataNoneExistIndexs; | |
234 | + } | |
235 | + | |
236 | + // 사용자 정의 예외 | |
237 | + public class LimitReachedException extends RuntimeException { | |
238 | + public LimitReachedException(String message) { | |
239 | + super(message); | |
240 | + } | |
241 | + } | |
242 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/handler/SheetHandler.java
... | ... | @@ -0,0 +1,456 @@ |
1 | +package com.takensoft.taken_bi_manager.common.file.handler; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
4 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
5 | +import org.apache.poi.ss.usermodel.BuiltinFormats; | |
6 | +import org.apache.poi.ss.usermodel.DataFormatter; | |
7 | +import org.apache.poi.ss.util.CellRangeAddress; | |
8 | +import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable; | |
9 | +import org.apache.poi.xssf.model.SharedStringsTable; | |
10 | +import org.apache.poi.xssf.model.StylesTable; | |
11 | +import org.apache.poi.xssf.usermodel.XSSFCellStyle; | |
12 | +import org.apache.poi.xssf.usermodel.XSSFRichTextString; | |
13 | +import org.xml.sax.Attributes; | |
14 | +import org.xml.sax.SAXException; | |
15 | +import org.xml.sax.helpers.DefaultHandler; | |
16 | + | |
17 | +import java.util.ArrayList; | |
18 | +import java.util.Arrays; | |
19 | +import java.util.List; | |
20 | + | |
21 | +//import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.xssfDataType; | |
22 | + | |
23 | +public class SheetHandler extends DefaultHandler { | |
24 | + | |
25 | + enum xssfDataType { | |
26 | + BOOLEAN, ERROR, FORMULA, INLINE_STRING, SST_STRING, NUMBER, NULL// 정우 추가 | |
27 | + } | |
28 | + | |
29 | + /** | |
30 | + * Table with the styles used for formatting | |
31 | + */ | |
32 | + private StylesTable stylesTable; | |
33 | + | |
34 | + private ReadOnlySharedStringsTable sharedStringsTable; | |
35 | + | |
36 | + /** | |
37 | + * Where our text is going | |
38 | + */ | |
39 | + private final Sheet2ListHandler output; | |
40 | + | |
41 | + // Set when V start element is seen | |
42 | + private boolean vIsOpen; | |
43 | + // Set when F start element is seen | |
44 | + private boolean fIsOpen; | |
45 | + // Set when an Inline String "is" is seen | |
46 | + private boolean isIsOpen; | |
47 | + // Set when a header/footer element is seen | |
48 | + private boolean hfIsOpen; | |
49 | + | |
50 | + // Set when cell start element is seen; | |
51 | + // used when cell close element is seen. | |
52 | + private xssfDataType nextDataType; | |
53 | + | |
54 | + // Used to format numeric cell values. | |
55 | + private short formatIndex; | |
56 | + private String formatString; | |
57 | + private final DataFormatter formatter; | |
58 | + | |
59 | + | |
60 | + //현재 cell or row의 위치 | |
61 | + private String excelRowPosition; | |
62 | + private String excelCellPosition; | |
63 | + | |
64 | + private String cellRef; | |
65 | + | |
66 | + private boolean formulasNotResults; | |
67 | + | |
68 | + // Gathers characters as they are seen. | |
69 | + private StringBuffer value = new StringBuffer(); | |
70 | + private StringBuffer formula = new StringBuffer(); | |
71 | + private StringBuffer headerFooter = new StringBuffer(); | |
72 | + | |
73 | + private SharedStringsTable sst; | |
74 | + private String lastContents; | |
75 | + private boolean nextIsString; | |
76 | + | |
77 | + //정우추가 | |
78 | + //private static final char[] EXCEL_CELL_NAMES = new char[] {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; | |
79 | + public static final List<Character> EXCEL_CELL_NAMES = Arrays.asList('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'); | |
80 | + | |
81 | + //이전에 처리 완료(데이터 담기 완료)한 row Index | |
82 | + private int proccessCompleteRowIndex = -1; | |
83 | + //이전에 처리 완료(데이터 담기 완료)한 Cell Index | |
84 | + private int proccessCompleteCellIndex = -1; | |
85 | + | |
86 | + public SheetHandler(StylesTable styles, ReadOnlySharedStringsTable strings, Sheet2ListHandler sheet2ListHandler, | |
87 | + DataFormatter dataFormatter, boolean formulasNotResults) { | |
88 | + this.stylesTable = styles; | |
89 | + this.sharedStringsTable = strings; | |
90 | + this.output = sheet2ListHandler; | |
91 | + this.formulasNotResults = formulasNotResults; | |
92 | + this.nextDataType = xssfDataType.NUMBER; | |
93 | + this.formatter = dataFormatter; | |
94 | + } | |
95 | + | |
96 | + public SheetHandler(StylesTable styles, ReadOnlySharedStringsTable strings, Sheet2ListHandler sheet2ListHandler, | |
97 | + boolean formulasNotResults) { | |
98 | + this(styles, strings, sheet2ListHandler, new DataFormatter(), formulasNotResults); | |
99 | + } | |
100 | + | |
101 | + private boolean isTextTag(String name) { | |
102 | + if ("v".equals(name)) { | |
103 | + // Easy, normal v text tag | |
104 | + return true; | |
105 | + } | |
106 | + if ("inlineStr".equals(name)) { | |
107 | + // Easy inline string | |
108 | + return true; | |
109 | + } | |
110 | + if ("t".equals(name) && isIsOpen) { | |
111 | + // Inline string <is><t>...</t></is> pair | |
112 | + return true; | |
113 | + } | |
114 | + // It isn't a text tag | |
115 | + return false; | |
116 | + } | |
117 | + | |
118 | + public void startElement(String url, String localName, String name, Attributes attributes) throws SAXException { | |
119 | + | |
120 | + name = StringUtil.replaceOnce(name, "x:", ""); | |
121 | + | |
122 | + if (isTextTag(name)) { | |
123 | + vIsOpen = true; | |
124 | + // Clear contents cache | |
125 | + value.setLength(0); | |
126 | + } else if ("is".equals(name)) { | |
127 | + // Inline string outer tag | |
128 | + isIsOpen = true; | |
129 | + } else if ("f".equals(name)) { | |
130 | + // Clear contents cache | |
131 | + formula.setLength(0); | |
132 | + | |
133 | + // Mark us as being a formula if not already | |
134 | + if (nextDataType == xssfDataType.NUMBER) { | |
135 | + nextDataType = xssfDataType.FORMULA; | |
136 | + } | |
137 | + | |
138 | + // Decide where to get the formula string from | |
139 | + String type = attributes.getValue("t"); | |
140 | + if (type != null && type.equals("shared")) { | |
141 | + // Is it the one that defines the shared, or uses it? | |
142 | + String ref = attributes.getValue("ref"); | |
143 | + String si = attributes.getValue("si"); | |
144 | + | |
145 | + if (ref != null) { | |
146 | + // This one defines it | |
147 | + // TODO Save it somewhere | |
148 | + fIsOpen = true; | |
149 | + } else { | |
150 | + // This one uses a shared formula | |
151 | + // TODO Retrieve the shared formula and tweak it to | |
152 | + // match the current cell | |
153 | + if (formulasNotResults) { | |
154 | + System.err.println("Warning - shared formulas not yet supported!"); | |
155 | + } else { | |
156 | + // It's a shared formula, so we can't get at the formula string yet | |
157 | + // However, they don't care about the formula string, so that's ok! | |
158 | + } | |
159 | + } | |
160 | + } else { | |
161 | + fIsOpen = true; | |
162 | + } | |
163 | + } else if ("oddHeader".equals(name) || "evenHeader".equals(name) || "firstHeader".equals(name) | |
164 | + || "firstFooter".equals(name) || "oddFooter".equals(name) || "evenFooter".equals(name)) { | |
165 | + hfIsOpen = true; | |
166 | + // Clear contents cache | |
167 | + headerFooter.setLength(0); | |
168 | + } else if ("row".equals(name)) { | |
169 | + //현재 row 엑셀 위치(1부터 시작) | |
170 | + this.excelRowPosition = attributes.getValue("r"); | |
171 | + | |
172 | + //row 생성 | |
173 | + output.startRow(this.excelRowPosition); | |
174 | + | |
175 | + //proccessCompleteCellIndex *초기화* - 'cell의 최초 시작 Index - 1' 값 담기 | |
176 | + this.proccessCompleteCellIndex = output.getFirstColumn() - 1; | |
177 | + | |
178 | + } | |
179 | + // c => cell | |
180 | + else if ("c".equals(name)) { | |
181 | + // Set up defaults. | |
182 | + this.nextDataType = xssfDataType.NUMBER; | |
183 | + this.formatIndex = -1; | |
184 | + this.formatString = null; | |
185 | + this.excelCellPosition = attributes.getValue("r"); | |
186 | + | |
187 | + String cellType = attributes.getValue("t"); | |
188 | + String cellStyleStr = attributes.getValue("s"); | |
189 | + | |
190 | + // cell 데이터 타입을 확인 | |
191 | + if ("b".equals(cellType)) | |
192 | + nextDataType = xssfDataType.BOOLEAN; | |
193 | + else if ("e".equals(cellType)) | |
194 | + nextDataType = xssfDataType.ERROR; | |
195 | + else if ("inlineStr".equals(cellType)) | |
196 | + nextDataType = xssfDataType.INLINE_STRING; | |
197 | + else if ("s".equals(cellType)) | |
198 | + nextDataType = xssfDataType.SST_STRING; | |
199 | + else if ("str".equals(cellType)) | |
200 | + nextDataType = xssfDataType.FORMULA; | |
201 | + else if (cellStyleStr != null) { | |
202 | + // Number, but almost certainly with a special style or format | |
203 | + int styleIndex = Integer.parseInt(cellStyleStr); | |
204 | + XSSFCellStyle style = stylesTable.getStyleAt(styleIndex); | |
205 | + if (style != null) { | |
206 | + this.formatIndex = style.getDataFormat(); | |
207 | + this.formatString = style.getDataFormatString(); | |
208 | + if (this.formatString == null) | |
209 | + this.formatString = BuiltinFormats.getBuiltinFormat(this.formatIndex); | |
210 | + } | |
211 | + } else if (cellType == null) {// 정우 추가 | |
212 | + nextDataType = xssfDataType.NULL;// 정우 추가 | |
213 | + } | |
214 | + | |
215 | + | |
216 | + | |
217 | + } else if ("mergeCells".equals(name)) { | |
218 | + output.findMerge(); | |
219 | + } else if ("mergeCell".equals(name)) { | |
220 | + for (int i = 0; i < attributes.getLength(); i++) { | |
221 | + | |
222 | + CellRangeAddress cra = CellRangeAddress.valueOf(attributes.getValue("ref")); | |
223 | + output.addMergeInfo(cra.getFirstRow(), cra.getFirstColumn(), cra.getLastRow(), cra.getLastColumn()); | |
224 | + } | |
225 | + } else if ("dimension".equals(name)) { | |
226 | + CellRangeAddress cra = CellRangeAddress.valueOf(attributes.getValue("ref")); | |
227 | + output.setFirstRow(cra.getFirstRow()); | |
228 | + output.setFirstColumn(cra.getFirstColumn()); | |
229 | + output.setLastRow(cra.getLastRow()); | |
230 | + output.setLastColumn(cra.getLastColumn()); | |
231 | + | |
232 | + //sheet 최초 시작시, 'row의 최초 시작 Index - 1' 값 담기 | |
233 | + this.proccessCompleteRowIndex = cra.getFirstRow() - 1; | |
234 | + //sheet 최초 시작시, 'cell의 최초 시작 Index - 1' 값 담기 | |
235 | + this.proccessCompleteCellIndex = cra.getFirstColumn() - 1; | |
236 | + | |
237 | + } else { | |
238 | + | |
239 | + } | |
240 | + } | |
241 | + | |
242 | + public void endElement(String uri, String localName, String name) throws SAXException { | |
243 | + name = StringUtil.replaceOnce(name, "x:", ""); | |
244 | + | |
245 | + String thisStr = null; | |
246 | + | |
247 | + // v => contents of a cell | |
248 | + if (isTextTag(name)) { | |
249 | + vIsOpen = false; | |
250 | + | |
251 | + if (nextDataType != null) { | |
252 | + // Process the value contents as required, now we have it all | |
253 | + switch (nextDataType) { | |
254 | + case BOOLEAN: | |
255 | + char first = value.charAt(0); | |
256 | + thisStr = first == '0' ? Boolean.valueOf(false).toString() : Boolean.valueOf(true).toString(); | |
257 | + break; | |
258 | + | |
259 | + case ERROR: | |
260 | + thisStr = value.toString(); | |
261 | + break; | |
262 | + | |
263 | + case FORMULA: | |
264 | + if (formulasNotResults) { | |
265 | + thisStr = value.toString(); | |
266 | + } else { | |
267 | + String fv = value.toString(); | |
268 | + | |
269 | + if (this.formatString != null) { | |
270 | + try { | |
271 | + // Try to use the value as a formattable number | |
272 | + double d = Double.parseDouble(fv); | |
273 | + thisStr = formatter.formatRawCellContents(d, this.formatIndex, this.formatString); | |
274 | + } catch (NumberFormatException e) { | |
275 | + // Formula is a String result not a Numeric one | |
276 | + thisStr = fv; | |
277 | + } | |
278 | + } else { | |
279 | + // No formating applied, just do raw value in all cases | |
280 | + thisStr = fv; | |
281 | + } | |
282 | + } | |
283 | + break; | |
284 | + | |
285 | + case INLINE_STRING: | |
286 | + // TODO: Can these ever have formatting on them? | |
287 | + XSSFRichTextString rtsi = new XSSFRichTextString(value.toString()); | |
288 | + thisStr = rtsi.toString(); | |
289 | + break; | |
290 | + case SST_STRING: | |
291 | + String sstIndex = value.toString(); | |
292 | + int idx = Integer.parseInt(sstIndex); | |
293 | +// XSSFRichTextString rtss = new XSSFRichTextString(sharedStringsTable.getItemAt(idx)); | |
294 | + thisStr = sharedStringsTable.getItemAt(idx).toString(); | |
295 | + break; | |
296 | + default: | |
297 | + XSSFRichTextString rtsi1 = new XSSFRichTextString(value.toString()); | |
298 | + thisStr = rtsi1.toString(); | |
299 | + break; | |
300 | + } | |
301 | + } | |
302 | + | |
303 | + /*현재 바라보고있는 row에서 [('이전의 cell Index(데이터 등록작업이 끝난 cell Index)' + 1) ~ ('현재 cell Index 전') 까지] cell 채우기*/ | |
304 | + fillCellsToCurrentCellIndex(); | |
305 | + | |
306 | + /*row에 'cell 데이터 추가'*/ | |
307 | + output.cellDataAdd(thisStr); | |
308 | + | |
309 | + /*처리 완료(데이터 담기 완료)된 cell Index 담기*/ | |
310 | + this.proccessCompleteCellIndex = getCurrentCellIndex(); | |
311 | + | |
312 | + } else if ("c".equals(name)) {// 정우 추가 | |
313 | + | |
314 | + } else if ("f".equals(name)) { | |
315 | + fIsOpen = false; | |
316 | + } else if ("is".equals(name)) { | |
317 | + isIsOpen = false; | |
318 | + } else if ("row".equals(name)) { | |
319 | + | |
320 | + /*현재 바라보고있는 sheet에서 [('이전의 row Index(데이터 등록작업이 끝난 row Index)' + 1) ~ ('현재 row Index' - 1) 까지] row 채우기 (현재 row 관련)*/ | |
321 | + fillRowsToCurrentRowIndex(); | |
322 | + | |
323 | + /*현재 row 데이터 추가전, 마지막 cell까지 다 채우기 (현재 cell 관련)*/ | |
324 | + fillCellsToCurrentCellIndex(this.proccessCompleteCellIndex, output.getLastColumn() + 1); | |
325 | + | |
326 | + /*rows(수집 데이터)에 'row 데이터 추가'*/ | |
327 | + output.endRow(); | |
328 | + | |
329 | + /*처리 완료(데이터 담기 완료)된 Row Index 담기*/ | |
330 | + this.proccessCompleteRowIndex = getCurrentRowIndex(); | |
331 | + | |
332 | + } else if ("oddHeader".equals(name) || "evenHeader".equals(name) || "firstHeader".equals(name)) { | |
333 | + hfIsOpen = false; | |
334 | + output.headerFooter(headerFooter.toString(), true, name); | |
335 | + } else if ("oddFooter".equals(name) || "evenFooter".equals(name) || "firstFooter".equals(name)) { | |
336 | + hfIsOpen = false; | |
337 | + output.headerFooter(headerFooter.toString(), false, name); | |
338 | + } else if ("worksheet".equals(name)) { | |
339 | + output.endEvent(); | |
340 | + } else { | |
341 | + | |
342 | + } | |
343 | + | |
344 | + nextDataType = null; | |
345 | + } | |
346 | + | |
347 | + | |
348 | + /** | |
349 | + * Captures characters only if a suitable element is open. Originally was just | |
350 | + * "v"; extended for inlineStr also. | |
351 | + */ | |
352 | + public void characters(char[] ch, int start, int length) throws SAXException { | |
353 | + if (vIsOpen) { | |
354 | + value.append(ch, start, length); | |
355 | + } | |
356 | + if (fIsOpen) { | |
357 | + formula.append(ch, start, length); | |
358 | + } | |
359 | + if (hfIsOpen) { | |
360 | + headerFooter.append(ch, start, length); | |
361 | + } | |
362 | + } | |
363 | + | |
364 | + /** | |
365 | + * 정우추가(cell관련) | |
366 | + * 현재 cell Index 가지고오기 | |
367 | + * - 기능 : excel cell 이름을 순번으로 바꾸기 ex)A -> 0, AA -> 27, ZZ -> 702 | |
368 | + */ | |
369 | + public int getCurrentCellIndex () { | |
370 | + //최종 Index | |
371 | + int index = -1; | |
372 | + | |
373 | + //A3 -> A | |
374 | + String cellName = CommonUtil.getOnlyText(this.excelCellPosition); | |
375 | + | |
376 | + //지수 | |
377 | + int quotient = 0; | |
378 | + | |
379 | + //맨 뒤에서 부터 한 문자씩 풀기 | |
380 | + for (int i = cellName.length() - 1; i >= 0; i--) { | |
381 | + char c = cellName.charAt(i); | |
382 | + int c_index = SheetHandler.EXCEL_CELL_NAMES.indexOf(c) + 1; | |
383 | + index += (int) Math.pow(SheetHandler.EXCEL_CELL_NAMES.size(), quotient++) * c_index; | |
384 | + } | |
385 | + | |
386 | + return index; | |
387 | + } | |
388 | + /** | |
389 | + * 정우추가(cell관련) | |
390 | + * 현재 바라보고있는 row에서 [('이전의 cell Index(데이터 등록작업이 끝난 cell Index)' + 1) ~ ('현재 cell Index' - 1) 까지] cell 채우기 | |
391 | + */ | |
392 | + public void fillCellsToCurrentCellIndex () { | |
393 | + fillCellsToCurrentCellIndex(this.proccessCompleteCellIndex, getCurrentCellIndex()); | |
394 | + } | |
395 | + /** | |
396 | + * 정우추가(cell관련) | |
397 | + * 현재 바라보고있는 row에서 [('startIndex' + 1) ~ ('endIndex 전') 까지] cell 채우기 | |
398 | + */ | |
399 | + public void fillCellsToCurrentCellIndex (int startIndex, int endIndex) { | |
400 | + if (endIndex - startIndex > 1) { | |
401 | + for (int i = startIndex + 1; i < endIndex; i++) { | |
402 | + output.getRow().add(null); | |
403 | + } | |
404 | + } | |
405 | + } | |
406 | + | |
407 | + /** | |
408 | + * 정우추가(row관련) | |
409 | + * 현재 row Index 가지고오기 | |
410 | + */ | |
411 | + public int getCurrentRowIndex () { | |
412 | + return (CommonUtil.parseInt((this.excelRowPosition)) - 1); | |
413 | + } | |
414 | + /** | |
415 | + * 정우추가(row관련) | |
416 | + * 현재 바라보고있는 sheet에서 [('이전의 row Index(데이터 등록작업이 끝난 row Index)' + 1) ~ ('현재 row Index' - 1) 까지] row 채우기 | |
417 | + */ | |
418 | + public void fillRowsToCurrentRowIndex () { | |
419 | + fillRowsToCurrentRowIndex(this.proccessCompleteRowIndex, getCurrentRowIndex()); | |
420 | + } | |
421 | + /** | |
422 | + * 정우추가(row관련) | |
423 | + * 현재 바라보고있는 sheet에서 [('startIndex' + 1) ~ ('endIndex 전') 까지] row 채우기 | |
424 | + */ | |
425 | + public void fillRowsToCurrentRowIndex (int startIndex, int endIndex) { | |
426 | + if (endIndex - startIndex > 1) { | |
427 | + for (int i = startIndex + 1; i < endIndex; i++) { | |
428 | + List<Object> row = new ArrayList<Object>(); | |
429 | + for (int j = output.getFirstColumn(); j <= output.getLastColumn(); j++) { | |
430 | + row.add(null); | |
431 | + } | |
432 | + output.getRows().add(row); | |
433 | + | |
434 | + //빈 Row Index 추가 | |
435 | + output.getRowDataNoneExistIndexs().add((output.getRows().size() - 1)); | |
436 | + } | |
437 | + } | |
438 | + } | |
439 | + | |
440 | + /** | |
441 | + * You need to implement this to handle the results of the sheet parsing. | |
442 | + */ | |
443 | + public interface SheetContentsHandler2 { | |
444 | + /** A row with the (zero based) row number has started */ | |
445 | + public void startRow(String currentRowIndex) throws SAXException; | |
446 | + | |
447 | + /** A row with the (zero based) row number has ended */ | |
448 | + public void endRow() throws Exception; | |
449 | + | |
450 | + /** A cell, with the given formatted value, was encountered */ | |
451 | + public void cellDataAdd(String formattedValue); | |
452 | + | |
453 | + /** A header or footer has been encountered */ | |
454 | + public void headerFooter(String text, boolean isHeader, String tagName); | |
455 | + } | |
456 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/service/FileManagerService.java
... | ... | @@ -0,0 +1,33 @@ |
1 | +package com.takensoft.taken_bi_manager.common.file.service; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.file.vo.CmmnFile; | |
4 | +import com.takensoft.taken_bi_manager.common.vo.CheckMessage; | |
5 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
6 | +import org.springframework.web.multipart.MultipartFile; | |
7 | + | |
8 | +public interface FileManagerService { | |
9 | + | |
10 | + /** | |
11 | + * @author 박민혁 | |
12 | + * @since 2024.04.24 | |
13 | + * | |
14 | + * 파일 정보 조회하기 | |
15 | + */ | |
16 | + public CustomeResultMap cmmnfileSelect(String fileManagerId) throws Exception; | |
17 | + | |
18 | + /** | |
19 | + * @author 박민혁 | |
20 | + * @since 2024.04.24 | |
21 | + * | |
22 | + * 멀티 파일 업로드 | |
23 | + */ | |
24 | + public CustomeResultMap cmmnfileUpload (MultipartFile[] files) throws Exception; | |
25 | + | |
26 | + /** | |
27 | + * @author 박민혁 | |
28 | + * @since 2024.04.24 | |
29 | + * | |
30 | + * 파일 삭제 | |
31 | + */ | |
32 | + public CustomeResultMap cmmnfileDelete(CmmnFile cmmnFile) throws Exception; | |
33 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/service/impl/FileManagerServiceImpl.java
... | ... | @@ -0,0 +1,138 @@ |
1 | +package com.takensoft.taken_bi_manager.common.file.service.impl; | |
2 | + | |
3 | +import com.jcraft.jsch.ChannelSftp; | |
4 | +import com.takensoft.taken_bi_manager.common.file.dao.FileDAO; | |
5 | +import com.takensoft.taken_bi_manager.common.file.service.FileManagerService; | |
6 | +import com.takensoft.taken_bi_manager.common.file.vo.CmmnFile; | |
7 | +import com.takensoft.taken_bi_manager.common.file.vo.FileManage; | |
8 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
9 | +import com.takensoft.taken_bi_manager.common.util.SftpUtil; | |
10 | +import com.takensoft.taken_bi_manager.common.vo.CheckMessage; | |
11 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
12 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode; | |
13 | +import com.takensoft.taken_bi_manager.host.service.SftpService; | |
14 | +import com.takensoft.taken_bi_manager.host.vo.ConnectionVO; | |
15 | +import com.takensoft.taken_bi_manager.host.vo.SftpVO; | |
16 | +import org.json.simple.JSONObject; | |
17 | +import org.springframework.beans.factory.annotation.Autowired; | |
18 | +import org.springframework.http.HttpStatus; | |
19 | +import org.springframework.stereotype.Service; | |
20 | +import org.springframework.transaction.annotation.Transactional; | |
21 | +import org.springframework.web.multipart.MultipartFile; | |
22 | + | |
23 | +import java.io.File; | |
24 | +import java.io.FileWriter; | |
25 | +import java.io.IOException; | |
26 | +import java.io.InputStream; | |
27 | +import java.nio.file.Files; | |
28 | +import java.nio.file.Path; | |
29 | +import java.nio.file.Paths; | |
30 | +import java.util.*; | |
31 | + | |
32 | +@Transactional | |
33 | +@Service | |
34 | +public class FileManagerServiceImpl implements FileManagerService { | |
35 | + | |
36 | + @Autowired | |
37 | + private FileDAO fileDAO; | |
38 | + @Autowired | |
39 | + private SftpService sftpService; | |
40 | + | |
41 | + /** | |
42 | + * @author 박민혁 | |
43 | + * @since 2024.04.24 | |
44 | + * | |
45 | + * 파일 정보 조회하기 | |
46 | + */ | |
47 | + @Override | |
48 | + public CustomeResultMap cmmnfileSelect(String fileManagerId) throws Exception{ | |
49 | + CustomeResultMap resultMap = new CustomeResultMap(); | |
50 | + resultMap.getResultData().put("cmmnFileList", fileDAO.cmmnfilesSelect(fileManagerId)); | |
51 | + | |
52 | + return resultMap; | |
53 | + } | |
54 | + | |
55 | + /** | |
56 | + * @author 박민혁 | |
57 | + * @since 2024.04.24 | |
58 | + * | |
59 | + * 멀티 파일 업로드 | |
60 | + */ | |
61 | + @Override | |
62 | + public CustomeResultMap cmmnfileUpload (MultipartFile[] files) throws Exception{ | |
63 | + CustomeResultMap resultMap = new CustomeResultMap(); | |
64 | + | |
65 | + List<CmmnFile> fileList = new ArrayList<>(); | |
66 | + FileManage fileManage = new FileManage(); | |
67 | + fileManage.setFileManagerId(CommonUtil.getRandKey("MFILE")); | |
68 | + fileManage.setFileType(SystemCode.FileType.ALL_FILE); | |
69 | + fileManage.setContentType("dataset"); | |
70 | + fileDAO.fileManagerInsert(fileManage); | |
71 | + | |
72 | + for (MultipartFile file : files) { | |
73 | + try { | |
74 | + String originalFileName = file.getOriginalFilename(); | |
75 | + String path = "C:\\Taken_BI_Manager\\cmmmfile\\"; | |
76 | + String fileName = UUID.randomUUID().toString() + "_" + originalFileName; | |
77 | + | |
78 | + File tempDir = new File(path); | |
79 | + if (!tempDir.exists()) { | |
80 | + tempDir.mkdirs(); | |
81 | + } | |
82 | + | |
83 | + Path savePath = Paths.get(path + fileName); | |
84 | + | |
85 | + // 파일 저장 | |
86 | + Files.copy(file.getInputStream(), savePath); | |
87 | + | |
88 | + CmmnFile fileInfo = new CmmnFile(); | |
89 | + fileInfo.setFileId(CommonUtil.getRandKey("FILE")); | |
90 | + fileInfo.setName(originalFileName); | |
91 | + fileInfo.setMaskName(fileName); | |
92 | + fileInfo.setSize(file.getSize()); | |
93 | + fileInfo.setContentType(null); | |
94 | + fileInfo.setFullPath(savePath.toString()); | |
95 | + fileInfo.setExtention(fileName.substring(fileName.lastIndexOf(".") + 1)); | |
96 | + fileInfo.setFileManagerId(fileManage.getFileManagerId()); | |
97 | + fileDAO.fileInsert(fileInfo); | |
98 | + | |
99 | + fileList.add(fileInfo); | |
100 | + } catch (Exception e) { | |
101 | + resultMap.getCheckMessage().setError("등록 실패 관리자에게 문의해주세요."); | |
102 | + } | |
103 | + } | |
104 | + resultMap.getResultData().put("fileManage", fileManage); | |
105 | + resultMap.getResultData().put("fileList", fileList); | |
106 | + resultMap.getCheckMessage().setMessage("success"); | |
107 | + | |
108 | + return resultMap; | |
109 | + } | |
110 | + | |
111 | + /** | |
112 | + * @author 박민혁 | |
113 | + * @since 2024.04.24 | |
114 | + * | |
115 | + * 파일 삭제 | |
116 | + */ | |
117 | + @Override | |
118 | + public CustomeResultMap cmmnfileDelete(CmmnFile cmmnFile) throws Exception{ | |
119 | + CustomeResultMap resultMap = new CustomeResultMap(); | |
120 | + | |
121 | + try{ | |
122 | + Path filePath = Paths.get(cmmnFile.getFullPath()); | |
123 | + if (Files.exists(filePath)) { | |
124 | + Files.delete(filePath); | |
125 | + | |
126 | + } else { | |
127 | + | |
128 | + } | |
129 | + | |
130 | + fileDAO.deleteCmmnFileToDataSetPost(cmmnFile.getFileManagerId()); | |
131 | + fileDAO.deleteFileManagerToDataSetPost(cmmnFile.getFileManagerId()); | |
132 | + }catch (Exception e) { | |
133 | + e.printStackTrace(); | |
134 | + } | |
135 | + | |
136 | + return resultMap; | |
137 | + } | |
138 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/vo/CmmnFile.java
... | ... | @@ -0,0 +1,48 @@ |
1 | +package com.takensoft.taken_bi_manager.common.file.vo; | |
2 | + | |
3 | +import java.sql.Timestamp; | |
4 | + | |
5 | +import lombok.Getter; | |
6 | +import lombok.Setter; | |
7 | + | |
8 | +/** | |
9 | + * @author 김성원 | |
10 | + * @since 2023-12-28 | |
11 | + * | |
12 | + * 공통파일 관리 객체 | |
13 | + */ | |
14 | +@Getter | |
15 | +@Setter | |
16 | +public class CmmnFile { | |
17 | + | |
18 | + // 파일ID | |
19 | + private String fileId; | |
20 | + | |
21 | + // 파일명 | |
22 | + private String name; | |
23 | + | |
24 | + // 파일 마스크 먕 | |
25 | + private String maskName; | |
26 | + | |
27 | + // 파일사이즈 | |
28 | + private long size; | |
29 | + | |
30 | + // 콘텐츠 타입? | |
31 | + private String contentType; | |
32 | + | |
33 | + // 파일 경로 | |
34 | + private String fullPath; | |
35 | + | |
36 | + // 파일 서브 경로 | |
37 | + private String subPath; | |
38 | + | |
39 | + // 파일 확장자 | |
40 | + private String extention; | |
41 | + | |
42 | + // 생성일 | |
43 | + private Timestamp creatDt; | |
44 | + | |
45 | + // 파일매니저 ID | |
46 | + private String fileManagerId; | |
47 | + | |
48 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/vo/FileInfo.java
... | ... | @@ -0,0 +1,182 @@ |
1 | +package com.takensoft.taken_bi_manager.common.file.vo; | |
2 | + | |
3 | +import java.io.File; | |
4 | + | |
5 | +import lombok.Getter; | |
6 | +import lombok.Setter; | |
7 | +import lombok.ToString; | |
8 | + | |
9 | +/** | |
10 | + * @author 김성원 | |
11 | + * @since 2024.01.12 | |
12 | + * | |
13 | + * 파일변환 관련 Object입니다. | |
14 | + */ | |
15 | +@Getter | |
16 | +@Setter | |
17 | +@ToString | |
18 | +public class FileInfo { | |
19 | + | |
20 | + /** | |
21 | + * 기본 생성자 | |
22 | + */ | |
23 | + public FileInfo() {} | |
24 | + | |
25 | + /** | |
26 | + * 생성자(파일) | |
27 | + */ | |
28 | + public FileInfo(File file) { | |
29 | + | |
30 | + this.file = file; | |
31 | + this.path = file.getPath(); | |
32 | + this.fileName = file.getName(); | |
33 | + | |
34 | + } | |
35 | + | |
36 | + /** | |
37 | + * 생성자(파일, 확장자) | |
38 | + */ | |
39 | + public FileInfo(File file, String fileFome) { | |
40 | + this.file = file; | |
41 | + this.fileFom = fileFome; | |
42 | + } | |
43 | + | |
44 | + | |
45 | + /** | |
46 | + * 생성자(파일및, 확장자, 구분자) | |
47 | + */ | |
48 | + public FileInfo(File file, String fileFome, String suffix) { | |
49 | + this.file = file; | |
50 | + this.fileFom = fileFome; | |
51 | + this.suffix = suffix; | |
52 | + | |
53 | + } | |
54 | + | |
55 | + /* | |
56 | + * 생성자 (fileInfo) | |
57 | + */ | |
58 | + public FileInfo(FileInfo fileInfo){ | |
59 | + this.file = fileInfo.getFile(); | |
60 | + this.path = fileInfo.getPath(); | |
61 | + this.fileName = fileInfo.getFileName(); | |
62 | + this.extension = fileInfo.getExtension(); | |
63 | + this.type = fileInfo.getType(); | |
64 | + this.lastData = fileInfo.isLastData(); | |
65 | + this.datasetAfter = fileInfo.isDatasetAfter(); | |
66 | + this.datasetId = fileInfo.getDatasetId(); | |
67 | + this.rowDataColumnIndex = fileInfo.getRowDataColumnIndex(); | |
68 | + this.startRowIndex = fileInfo.getStartRowIndex(); | |
69 | + this.startCellIndex = fileInfo.getStartCellIndex(); | |
70 | + this.streOptn = fileInfo.isStreOptn(); | |
71 | + this.fileFom = fileInfo.getFileFom(); | |
72 | + this.suffix = fileInfo.getSuffix(); | |
73 | + this.addDay = fileInfo.getAddDay(); | |
74 | + this.addMonth = fileInfo.getAddMonth(); | |
75 | + this.delimiter = fileInfo.getDelimiter(); | |
76 | + this.viewMode = fileInfo.isViewMode(); | |
77 | + } | |
78 | + | |
79 | + /** | |
80 | + * 관리 파일 | |
81 | + */ | |
82 | + private File file; | |
83 | + | |
84 | + /** | |
85 | + * 파일 경로 | |
86 | + */ | |
87 | + private String path; | |
88 | + | |
89 | + /** | |
90 | + * 파일 명 | |
91 | + */ | |
92 | + private String fileName; | |
93 | + | |
94 | + /** | |
95 | + * 파일 확장자 | |
96 | + */ | |
97 | + private String extension; | |
98 | + | |
99 | + /** | |
100 | + * 파일 수집 타입 : 전체, 포함, 특정 | |
101 | + */ | |
102 | + private String type; | |
103 | + | |
104 | + /** | |
105 | + * 마지막 파일 옵션 | |
106 | + */ | |
107 | + private boolean lastData; | |
108 | + | |
109 | + /** | |
110 | + * 데이터셋 업데이트 보다 최신 파일만 선택 옵션 | |
111 | + */ | |
112 | + private boolean datasetAfter; | |
113 | + | |
114 | + /** | |
115 | + * 데이터셋 아이디 | |
116 | + */ | |
117 | + private String datasetId; | |
118 | + | |
119 | + /** | |
120 | + * 데이터(행,열)의 컬럼인 Row의 Index | |
121 | + */ | |
122 | + private int rowDataColumnIndex; | |
123 | + | |
124 | + /** | |
125 | + * 데이터(행,열)의 Row 시작 Index | |
126 | + */ | |
127 | + private int startRowIndex; | |
128 | + | |
129 | + /** | |
130 | + * 데이터(행,열)의 Cell 시작 Index | |
131 | + */ | |
132 | + private int startCellIndex; | |
133 | + | |
134 | + /** | |
135 | + * 파일 쓰기 옵션 | |
136 | + */ | |
137 | + private boolean streOptn = false; | |
138 | + | |
139 | + /** | |
140 | + * 파일 타입 : xlsx, xls, csv, text, json, xml ... | |
141 | + */ | |
142 | + private String fileFom = "xlsx"; | |
143 | + | |
144 | + /** | |
145 | + * 날짜시간 형식 | |
146 | + */ | |
147 | + private String suffix = "_YYYYMMDDHHmmss"; | |
148 | + | |
149 | + /** | |
150 | + * 일계산 | |
151 | + */ | |
152 | + private int addDay = 0; | |
153 | + | |
154 | + /** | |
155 | + * 월계산 (하석형 추가) | |
156 | + */ | |
157 | + private int addMonth = 0; | |
158 | + | |
159 | + /** | |
160 | + * file 구분자 | |
161 | + */ | |
162 | + private String delimiter = ","; | |
163 | + | |
164 | + /** | |
165 | + * 파일 미리보기 옵션 | |
166 | + */ | |
167 | + private boolean viewMode; | |
168 | + | |
169 | + //추가 dataset_post_id | |
170 | + private String dataset_post_id; | |
171 | + | |
172 | + | |
173 | + | |
174 | + | |
175 | + public void fileToFileInfo(File file) { | |
176 | + | |
177 | + this.file = file; | |
178 | + this.path = file.getPath(); | |
179 | + this.fileName = file.getName(); | |
180 | + | |
181 | + } | |
182 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/vo/FileManage.java
... | ... | @@ -0,0 +1,132 @@ |
1 | +package com.takensoft.taken_bi_manager.common.file.vo; | |
2 | + | |
3 | + | |
4 | +import java.sql.Timestamp; | |
5 | +import java.util.Date; | |
6 | + | |
7 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.FileType; | |
8 | + | |
9 | +import lombok.Getter; | |
10 | +import lombok.Setter; | |
11 | + | |
12 | + | |
13 | + | |
14 | +/** | |
15 | + * @author 김성원 | |
16 | + * @since 2023.12.29 | |
17 | + * | |
18 | + * File 관리 Domain 입니다. | |
19 | + */ | |
20 | +@Getter | |
21 | +@Setter | |
22 | +public class FileManage { | |
23 | + | |
24 | + public FileManage() {}; | |
25 | + | |
26 | + public FileManage(String fileManagerId) { | |
27 | + this.fileManagerId = fileManagerId; | |
28 | + }; | |
29 | + | |
30 | + public FileManage(long fileSeq) { | |
31 | + this.fileId = fileSeq; | |
32 | + }; | |
33 | + | |
34 | + public FileManage(String fileManagerId, long fileSeq) { | |
35 | + this.fileManagerId = fileManagerId; | |
36 | + this.fileId = fileSeq; | |
37 | + }; | |
38 | + | |
39 | + public FileManage(FileType fileType) { | |
40 | + this.fileType = fileType; | |
41 | + }; | |
42 | + | |
43 | + public FileManage(FileType fileType, String contentType) { | |
44 | + this.fileType = fileType; | |
45 | + this.contentType = contentType; | |
46 | + }; | |
47 | + | |
48 | + public FileManage(String fileManagerId, FileType fileType) { | |
49 | + this.fileManagerId = fileManagerId; | |
50 | + this.fileType = fileType; | |
51 | + }; | |
52 | + | |
53 | + public FileManage(String fileManagerId, FileType fileType, String contentType) { | |
54 | + this.fileManagerId = fileManagerId; | |
55 | + this.fileType = fileType; | |
56 | + this.contentType = contentType; | |
57 | + }; | |
58 | + | |
59 | + /** | |
60 | + * 파일 관리 아이디 | |
61 | + */ | |
62 | + private String fileManagerId; | |
63 | + | |
64 | + /** | |
65 | + * 파일 타입 | |
66 | + */ | |
67 | + private FileType fileType; | |
68 | + | |
69 | + /** | |
70 | + * 등록한 컨텐츠 타입 | |
71 | + */ | |
72 | + private String contentType; | |
73 | + | |
74 | + /** | |
75 | + * 파일 SEQ | |
76 | + */ | |
77 | + private long fileId; | |
78 | + | |
79 | + /** | |
80 | + * 파일명 | |
81 | + */ | |
82 | + private String name; | |
83 | + | |
84 | + /** | |
85 | + * 마스크 파일명 | |
86 | + */ | |
87 | + private String maskName; | |
88 | + | |
89 | + /** | |
90 | + * 파일 사이즈. | |
91 | + */ | |
92 | + private long size; | |
93 | + | |
94 | + /** | |
95 | + * 서브 디렉토리. | |
96 | + */ | |
97 | + private String subDir; | |
98 | + | |
99 | + /** | |
100 | + * 데이터 셋 파일 절대 경로 | |
101 | + */ | |
102 | + private String fullDir; | |
103 | + | |
104 | + /** | |
105 | + * 파일 확장자. | |
106 | + */ | |
107 | + private String extension; | |
108 | + | |
109 | + /** | |
110 | + * 파일 생성일. | |
111 | + */ | |
112 | + private Date createDate; | |
113 | + | |
114 | + | |
115 | + | |
116 | + | |
117 | + | |
118 | + /** | |
119 | + * file 관련 메세지 | |
120 | + */ | |
121 | + //private CheckMessage checkMessage = new CheckMessage(); | |
122 | + | |
123 | +// public CheckMessage getCheckMessage() { | |
124 | +// return checkMessage; | |
125 | +// } | |
126 | +// | |
127 | +// public void setCheckMessage(CheckMessage checkMessage) { | |
128 | +// this.checkMessage = checkMessage; | |
129 | +// } | |
130 | + | |
131 | + | |
132 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/file/web/FileManagerController.java
... | ... | @@ -0,0 +1,66 @@ |
1 | +package com.takensoft.taken_bi_manager.common.file.web; | |
2 | + | |
3 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
4 | +import com.takensoft.taken_bi_manager.common.file.service.FileManagerService; | |
5 | +import com.takensoft.taken_bi_manager.common.file.vo.CmmnFile; | |
6 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
7 | +import jakarta.servlet.http.HttpServletResponse; | |
8 | +import lombok.RequiredArgsConstructor; | |
9 | +import org.springframework.web.bind.annotation.*; | |
10 | +import org.springframework.web.multipart.MultipartFile; | |
11 | + | |
12 | +import java.io.File; | |
13 | +import java.io.FileInputStream; | |
14 | +import java.io.OutputStream; | |
15 | +import java.net.URLEncoder; | |
16 | +import java.util.HashMap; | |
17 | +import java.util.List; | |
18 | +import java.util.Map; | |
19 | + | |
20 | +@RestController | |
21 | +@RequiredArgsConstructor | |
22 | +@RequestMapping("/fileManage") | |
23 | +public class FileManagerController { | |
24 | + private final FileManagerService fileManagerService; | |
25 | + | |
26 | + /** | |
27 | + * @author 박민혁 | |
28 | + * @since 2024.04.24 | |
29 | + * | |
30 | + * 파일 정보 조회하기 | |
31 | + */ | |
32 | + @PostMapping("/read") | |
33 | + public CustomeResultMap cmmnfileUpload (@RequestParam("files") MultipartFile[] files) throws Exception { | |
34 | + CustomeResultMap map = fileManagerService.cmmnfileUpload(files); | |
35 | + return map; | |
36 | + } | |
37 | + | |
38 | + /** | |
39 | + * @author 박민혁 | |
40 | + * @since 2024.04.25 | |
41 | + * | |
42 | + * 파일 정보 다운로드 | |
43 | + */ | |
44 | + @PostMapping("/download") | |
45 | + public void cmmnfileDownload (@RequestBody HashMap<String ,Object> params, HttpServletResponse response) throws Exception { | |
46 | + CustomeResultMap map = fileManagerService.cmmnfileSelect((String) params.get("fileManagerId")); | |
47 | + File downloadFile = null; | |
48 | + List<CmmnFile> cmmnFiles = (List<CmmnFile>) map.getResultData().get("cmmnFileList"); | |
49 | + if(cmmnFiles != null){ | |
50 | + String filePath = cmmnFiles.get(0).getFullPath(); | |
51 | + downloadFile = new File(filePath); | |
52 | + | |
53 | + response.setContentType("application/octet-stream"); | |
54 | + response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(cmmnFiles.get(0).getName(), "UTF-8") + "\""); | |
55 | + response.setHeader("Content-Transfer-Encoding", "binary"); | |
56 | + | |
57 | + try (OutputStream out = response.getOutputStream(); FileInputStream fis = new FileInputStream(downloadFile)) { | |
58 | + byte[] buffer = new byte[1024]; | |
59 | + int bytesRead; | |
60 | + while ((bytesRead = fis.read(buffer)) != -1) { | |
61 | + out.write(buffer, 0, bytesRead); | |
62 | + } | |
63 | + } | |
64 | + } | |
65 | + } | |
66 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/schedule/dao/ScheduleDAO.java
... | ... | @@ -0,0 +1,68 @@ |
1 | +package com.takensoft.taken_bi_manager.common.schedule.dao; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.schedule.vo.Schedule; | |
4 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
5 | +import com.takensoft.taken_bi_manager.common.vo.SearchVO; | |
6 | +import org.apache.ibatis.annotations.Mapper; | |
7 | + | |
8 | +import java.util.HashMap; | |
9 | +import java.util.List; | |
10 | + | |
11 | +@Mapper | |
12 | +public interface ScheduleDAO { | |
13 | + /** | |
14 | + * @author 김성원 | |
15 | + * @since 2021.01.24 | |
16 | + * | |
17 | + * 스케줄 등록 | |
18 | + */ | |
19 | + public int conflictInsertSchedule (Schedule schedule) throws Exception; | |
20 | + | |
21 | + /** | |
22 | + * @author 김성원 | |
23 | + * @since 2021.01.24 | |
24 | + * | |
25 | + * 스케줄 목록 조회 | |
26 | + */ | |
27 | + public List<Schedule> selectScheduleList (SearchVO searchVO) throws Exception; | |
28 | + | |
29 | + /** | |
30 | + * @author 김성원 | |
31 | + * @since 2021.01.24 | |
32 | + * | |
33 | + * 스케줄 목록 개수 조회 | |
34 | + */ | |
35 | + public int selectScheduleListCount (SearchVO searchVO) throws Exception; | |
36 | + | |
37 | + /** | |
38 | + * @author 김성원 | |
39 | + * @since 2021.01.24 | |
40 | + * | |
41 | + * 스케줄 상세 조회 | |
42 | + */ | |
43 | + public Schedule selectSchedule (String id) throws Exception; | |
44 | + | |
45 | + /** | |
46 | + * @author 박정하 | |
47 | + * @since 2024.10.04 | |
48 | + * | |
49 | + * Diagram Id로 Schedule Id 구하기 | |
50 | + */ | |
51 | + public String selectScheduleIdRead(String diagramId) throws Exception; | |
52 | + | |
53 | + /** | |
54 | + * @author 박정하 | |
55 | + * @since 2024.10.04 | |
56 | + * | |
57 | + * 스케줄 정보 삭제 | |
58 | + */ | |
59 | + public int deleteSchedule(String schdulId) throws Exception; | |
60 | + | |
61 | + /** | |
62 | + * @author 박정하 | |
63 | + * @since 2024.10.04 | |
64 | + * | |
65 | + * 스케줄 상태 변경 | |
66 | + */ | |
67 | + public int scheduleSttusChange(HashMap<String, Object> params) throws Exception; | |
68 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/schedule/service/ScheduleService.java
... | ... | @@ -0,0 +1,47 @@ |
1 | +package com.takensoft.taken_bi_manager.common.schedule.service; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.schedule.vo.Schedule; | |
4 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
5 | +import com.takensoft.taken_bi_manager.common.vo.SearchVO; | |
6 | + | |
7 | +public interface ScheduleService { | |
8 | + /** | |
9 | + * @author 김성원 | |
10 | + * @since 2021.01.24 | |
11 | + * | |
12 | + * 스케줄 등록 | |
13 | + */ | |
14 | + public int conflictInsertSchedule (Schedule schedule) throws Exception; | |
15 | + | |
16 | + /** | |
17 | + * @author 김성원 | |
18 | + * @since 2021.01.24 | |
19 | + * | |
20 | + * 스케줄 목록 조회 | |
21 | + */ | |
22 | + public CustomeResultMap selectScheduleList (SearchVO searchVO) throws Exception; | |
23 | + | |
24 | + /** | |
25 | + * @author 김성원 | |
26 | + * @since 2021.01.24 | |
27 | + * | |
28 | + * 스케줄 상세 조회 | |
29 | + */ | |
30 | + public Schedule selectSchedule (Schedule schedule) throws Exception; | |
31 | + | |
32 | + /** | |
33 | + * @author 박정하 | |
34 | + * @since 2024.10.04 | |
35 | + * | |
36 | + * 스케줄 정보 삭제 | |
37 | + */ | |
38 | + public CustomeResultMap deleteSchedule(String schdulId) throws Exception; | |
39 | + | |
40 | + /** | |
41 | + * @author 박정하 | |
42 | + * @since 2024.10.04 | |
43 | + * | |
44 | + * 스케줄 상태 변경 | |
45 | + */ | |
46 | + public CustomeResultMap scheduleSttusChange(String schdulId, String schdulSttus) throws Exception; | |
47 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/schedule/service/impl/ScheduleServiceImpl.java
... | ... | @@ -0,0 +1,91 @@ |
1 | +package com.takensoft.taken_bi_manager.common.schedule.service.impl; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.schedule.dao.ScheduleDAO; | |
4 | +import com.takensoft.taken_bi_manager.common.schedule.service.ScheduleService; | |
5 | +import com.takensoft.taken_bi_manager.common.schedule.vo.Schedule; | |
6 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
7 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
8 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
9 | +import com.takensoft.taken_bi_manager.common.vo.SearchVO; | |
10 | +import com.takensoft.taken_bi_manager.jobs.service.JobService; | |
11 | +import org.springframework.beans.factory.annotation.Autowired; | |
12 | +import org.springframework.stereotype.Service; | |
13 | + | |
14 | +import java.util.HashMap; | |
15 | + | |
16 | +@Service | |
17 | +public class ScheduleServiceImpl implements ScheduleService { | |
18 | + @Autowired | |
19 | + private ScheduleDAO scheduleDAO; | |
20 | + | |
21 | + @Autowired | |
22 | + private JobService jobService; | |
23 | + | |
24 | + /* | |
25 | + * 스케줄 등록 | |
26 | + */ | |
27 | + @Override | |
28 | + public int conflictInsertSchedule(Schedule schedule) throws Exception { | |
29 | + String group_id = jobService.insertJobGroup(schedule.getJobGroup()).getResultData().get("group_id").toString(); | |
30 | + schedule.setGroup_id(group_id); | |
31 | + if(StringUtil.isEmpty(schedule.getSchdul_id())){ | |
32 | + schedule.setSchdul_id(CommonUtil.getRandKey("SCHEDULE")); | |
33 | + schedule.setCreatId(CommonUtil.getLoginUserId()); | |
34 | + }else{ | |
35 | + schedule.setUpdtId(CommonUtil.getLoginUserId()); | |
36 | + } | |
37 | + return scheduleDAO.conflictInsertSchedule(schedule); | |
38 | + } | |
39 | + | |
40 | + /* | |
41 | + * 스케줄 목록 조회 | |
42 | + */ | |
43 | + @Override | |
44 | + public CustomeResultMap selectScheduleList(SearchVO searchVO) throws Exception { | |
45 | + int totalRows = scheduleDAO.selectScheduleListCount(searchVO); | |
46 | + searchVO.setTotalRows(totalRows); | |
47 | + CustomeResultMap map = new CustomeResultMap(); | |
48 | + map.getResultData().put("scheduleList", scheduleDAO.selectScheduleList(searchVO)); | |
49 | + map.getResultData().put("searchVO", searchVO); | |
50 | + return map; | |
51 | + } | |
52 | + | |
53 | + /* | |
54 | + * 스케줄 상세 조회 | |
55 | + */ | |
56 | + @Override | |
57 | + public Schedule selectSchedule(Schedule schedule) throws Exception { | |
58 | + Schedule sc = scheduleDAO.selectSchedule(schedule.getSchdul_id()); | |
59 | + sc.setJobGroup(jobService.selectJobGroup(sc.getGroup_id())); | |
60 | + return sc; | |
61 | + } | |
62 | + | |
63 | + /** | |
64 | + * @author 박정하 | |
65 | + * @since 2024.10.04 | |
66 | + * | |
67 | + * 스케줄 정보 삭제 | |
68 | + */ | |
69 | + @Override | |
70 | + public CustomeResultMap deleteSchedule(String schdulId) throws Exception { | |
71 | + CustomeResultMap result = new CustomeResultMap(); | |
72 | + result.getResultData().put("updateResult", scheduleDAO.deleteSchedule(schdulId)); | |
73 | + return result; | |
74 | + } | |
75 | + | |
76 | + /** | |
77 | + * @author 박정하 | |
78 | + * @since 2024.10.04 | |
79 | + * | |
80 | + * 스케줄 상태 변경 | |
81 | + */ | |
82 | + @Override | |
83 | + public CustomeResultMap scheduleSttusChange(String schdulId, String schdulSttus) throws Exception { | |
84 | + CustomeResultMap result = new CustomeResultMap(); | |
85 | + HashMap<String, Object> params = new HashMap<>(); | |
86 | + params.put("schdulId", schdulId); | |
87 | + params.put("schdulSttus", schdulSttus); | |
88 | + result.getResultData().put("updateResult", scheduleDAO.scheduleSttusChange(params)); | |
89 | + return result; | |
90 | + } | |
91 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/schedule/vo/Schedule.java
... | ... | @@ -0,0 +1,86 @@ |
1 | +package com.takensoft.taken_bi_manager.common.schedule.vo; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.jobs.vo.JobGroup; | |
4 | +import lombok.Getter; | |
5 | +import lombok.Setter; | |
6 | + | |
7 | +import java.io.Serializable; | |
8 | +import java.sql.Timestamp; | |
9 | +import java.util.*; | |
10 | + | |
11 | +/** | |
12 | + * @author 김성원 | |
13 | + * @since 2021.12.28 | |
14 | + * | |
15 | + * 스케줄러 Domain 입니다. | |
16 | + */ | |
17 | +@Getter | |
18 | +@Setter | |
19 | +public class Schedule implements Serializable { | |
20 | + // 시리얼 버전 | |
21 | + private static final long serialVersionUID = 1L; | |
22 | + | |
23 | + // 스케줄러 고유 ID | |
24 | + private String schdul_id; | |
25 | + | |
26 | + // 스케줄러 그룹 id | |
27 | + private String group_id; | |
28 | + | |
29 | + // 스케줄러 명 | |
30 | + private String sj; | |
31 | + | |
32 | + // 스케줄러 명 | |
33 | + private String dc; | |
34 | + | |
35 | + // 스케쥴링 | |
36 | + private String cron; | |
37 | + | |
38 | + // cron 스케쥴링 한글 | |
39 | + private String cron_chrctr; | |
40 | + | |
41 | + // 스케쥴링 상태 | |
42 | + private String schdul_sttus = "run"; | |
43 | + | |
44 | + // 생성일 | |
45 | + private Timestamp creatDt; | |
46 | + | |
47 | + // 생성자ID | |
48 | + private String creatId; | |
49 | + | |
50 | + // 수정일 | |
51 | + private Timestamp updtDt; | |
52 | + | |
53 | + // 수정자 ID | |
54 | + private String updtId; | |
55 | + | |
56 | + /** | |
57 | + * 주기적 인지 아닌지 | |
58 | + * true: 주기적 | |
59 | + * false: 일시적 | |
60 | + */ | |
61 | + private boolean cycle_at; | |
62 | + | |
63 | + /** | |
64 | + * 사용여부(삭제 여부) | |
65 | + */ | |
66 | + private boolean use_at = true; | |
67 | + | |
68 | + /** | |
69 | + * 에러 존재 유무 | |
70 | + */ | |
71 | + private boolean error_at = false; | |
72 | + | |
73 | + private boolean isUsehighClassOption = false; | |
74 | + | |
75 | + private JobGroup jobGroup; | |
76 | + | |
77 | + /** | |
78 | + * 에러 로그 리스트 | |
79 | + */ | |
80 | + private List<ScheduleLog> ScheduleLogs; | |
81 | + | |
82 | + public Schedule(){ | |
83 | + ScheduleLogs = new ArrayList<>(); | |
84 | + jobGroup = new JobGroup(); | |
85 | + } | |
86 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/schedule/vo/ScheduleLog.java
... | ... | @@ -0,0 +1,66 @@ |
1 | +package com.takensoft.taken_bi_manager.common.schedule.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +import java.io.Serializable; | |
7 | + | |
8 | +/** | |
9 | + * @author 김성원 | |
10 | + * @since 2024 02.26 | |
11 | + * | |
12 | + * 스케줄러 Domain 상세정보 입니다. | |
13 | + */ | |
14 | +@Getter | |
15 | +@Setter | |
16 | +public class ScheduleLog implements Serializable { | |
17 | + | |
18 | + /** | |
19 | + * 시리얼 버전 | |
20 | + */ | |
21 | + private static final long serialVersionUID = 1L; | |
22 | + | |
23 | + /** | |
24 | + * 스케줄러 고유 ID | |
25 | + */ | |
26 | + private String schdulId; | |
27 | + | |
28 | + | |
29 | + /** | |
30 | + * 실행일 | |
31 | + */ | |
32 | + private String executDe; | |
33 | + | |
34 | + | |
35 | + /** | |
36 | + * 스케쥴링 상태 | |
37 | + */ | |
38 | + private String schdulSttus; | |
39 | + | |
40 | + | |
41 | + /** | |
42 | + * 로그정보 | |
43 | + */ | |
44 | + private String logInfo; | |
45 | + | |
46 | + | |
47 | + /** | |
48 | + * Job 의 타입코드입니다.(공통코드 참조예정) | |
49 | + */ | |
50 | + private String jobCode; | |
51 | + | |
52 | + | |
53 | + /** | |
54 | + * 실행 순서 | |
55 | + */ | |
56 | + private int indx; | |
57 | + | |
58 | + | |
59 | + /** | |
60 | + * 오류 사항 확인 유무 | |
61 | + */ | |
62 | + private boolean success; | |
63 | + | |
64 | + | |
65 | + | |
66 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/Background_style.java
... | ... | @@ -0,0 +1,45 @@ |
1 | +package com.takensoft.taken_bi_manager.common.stylesheet.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +/** | |
7 | + * @author 김성원 | |
8 | + * @since 2024.02.27 | |
9 | + * | |
10 | + * 백그라운드 옵션 | |
11 | + */ | |
12 | + | |
13 | +@Getter | |
14 | +@Setter | |
15 | +public class Background_style { | |
16 | + | |
17 | + // 스타일 시트 ID | |
18 | + private String stylesheet_id; | |
19 | + | |
20 | + // 스타일 인덱스 | |
21 | + private int indx; | |
22 | + | |
23 | + // 백그라운드 타입 | |
24 | + private boolean image_at; | |
25 | + | |
26 | + // 백그라운드 타입 | |
27 | + private boolean imageType; | |
28 | + | |
29 | + // 색상 | |
30 | + private String background_color; | |
31 | + | |
32 | + // 투명도 | |
33 | + private int opacity; | |
34 | + | |
35 | + // 이미지 url | |
36 | + private String imageUrl; | |
37 | + | |
38 | + public Background_style(){ | |
39 | + this.image_at = false; | |
40 | + this.opacity = 0; | |
41 | + this.background_color = "#ffffff"; | |
42 | + this.imageType = false; | |
43 | + } | |
44 | + | |
45 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/BorderStyle.java
... | ... | @@ -0,0 +1,43 @@ |
1 | +package com.takensoft.taken_bi_manager.common.stylesheet.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +import java.util.ArrayList; | |
7 | +import java.util.List; | |
8 | + | |
9 | +/** | |
10 | + * @author 김성원 | |
11 | + * @since 2024.02.27 | |
12 | + * | |
13 | + * 보더 옵션 관련 스타일 시트 | |
14 | + */ | |
15 | +@Getter | |
16 | +@Setter | |
17 | +public class BorderStyle { | |
18 | + | |
19 | + // 스타일 시트 ID | |
20 | + private String stylesheet_id; | |
21 | + | |
22 | + // 스타일 인덱스 | |
23 | + private int indx; | |
24 | + | |
25 | + // 보더 스타일 | |
26 | + private String border_style; | |
27 | + | |
28 | + private String border_color; | |
29 | + | |
30 | + // 스타일 아이템 | |
31 | + private List<BorderStyleItm> border_item; | |
32 | + | |
33 | + public BorderStyle(){ | |
34 | + this.border_style = "none"; | |
35 | + this.border_color = "#8e8e8e"; | |
36 | + border_item = new ArrayList<>(); | |
37 | + border_item.add(new BorderStyleItm()); | |
38 | + border_item.add(new BorderStyleItm()); | |
39 | + border_item.add(new BorderStyleItm()); | |
40 | + border_item.add(new BorderStyleItm()); | |
41 | + } | |
42 | + | |
43 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/BorderStyleItm.java
... | ... | @@ -0,0 +1,20 @@ |
1 | +package com.takensoft.taken_bi_manager.common.stylesheet.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +@Getter | |
7 | +@Setter | |
8 | +public class BorderStyleItm { | |
9 | + | |
10 | + // 보더 두께 | |
11 | + private int border_width; | |
12 | + | |
13 | + // 보더 라운드 | |
14 | + private int border_radius; | |
15 | + | |
16 | + public BorderStyleItm(){ | |
17 | + this.border_width = 2; | |
18 | + this.border_radius = 0; | |
19 | + } | |
20 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/FontStyle.java
... | ... | @@ -0,0 +1,62 @@ |
1 | +package com.takensoft.taken_bi_manager.common.stylesheet.vo; | |
2 | + | |
3 | + | |
4 | +import lombok.Getter; | |
5 | +import lombok.Setter; | |
6 | + | |
7 | +/** | |
8 | + * @author 김성원 | |
9 | + * @since 2024.02.27 | |
10 | + * | |
11 | + * 폰트 옵션 관리 VO 입니다. | |
12 | + */ | |
13 | +@Getter | |
14 | +@Setter | |
15 | +public class FontStyle { | |
16 | + | |
17 | + // 스타일 시트 ID | |
18 | + private String stylesheet_id; | |
19 | + | |
20 | + // 스타일 인덱스 | |
21 | + private int indx; | |
22 | + | |
23 | + // 폰트 | |
24 | + private String font; | |
25 | + | |
26 | + // 폰트 사이즈 | |
27 | + private double font_size; | |
28 | + | |
29 | + // 폰트 컬러 | |
30 | + private String font_color; | |
31 | + | |
32 | + // 볼드 유무 | |
33 | + private boolean bold_at; | |
34 | + | |
35 | + // 기울기 유무 | |
36 | + private boolean italic_at; | |
37 | + | |
38 | + // 언더라인 유무 | |
39 | + private boolean underline_at; | |
40 | + | |
41 | + // 가운데라인 유무 | |
42 | + private boolean line_through_at; | |
43 | + | |
44 | + // 폰트 정렬(좌우) | |
45 | + private String text_align; | |
46 | + | |
47 | + // 폰트 정렬(상하) | |
48 | + private String vertical_align; | |
49 | + | |
50 | + public FontStyle(){ | |
51 | + this.font = "Pretendard"; | |
52 | + this.font_size = 11; | |
53 | + this.font_color = "#000000"; | |
54 | + this.bold_at = false; | |
55 | + this.italic_at = false; | |
56 | + this.underline_at = false; | |
57 | + this.line_through_at = false; | |
58 | + this.text_align = "left"; | |
59 | + this.vertical_align = "middle"; | |
60 | + } | |
61 | + | |
62 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/PaddingAndMargin.java
... | ... | @@ -0,0 +1,58 @@ |
1 | +package com.takensoft.taken_bi_manager.common.stylesheet.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +/** | |
7 | + * @author 김성원 | |
8 | + * @since 2024.02.27 | |
9 | + * | |
10 | + * 패딩 마진 옵션 | |
11 | + */ | |
12 | +@Getter | |
13 | +@Setter | |
14 | +public class PaddingAndMargin { | |
15 | + | |
16 | + // 스타일 시트 ID | |
17 | + private String stylesheet_id; | |
18 | + | |
19 | + // 스타일 인덱스 | |
20 | + private int indx; | |
21 | + | |
22 | + // 마진 | |
23 | + private double margin_top; | |
24 | + | |
25 | + // 패딩 | |
26 | + private double padding_top; | |
27 | + | |
28 | + // 마진 | |
29 | + private double margin_left; | |
30 | + | |
31 | + // 패딩 | |
32 | + private double padding_left; | |
33 | + | |
34 | + // 마진 | |
35 | + private double margin_right; | |
36 | + | |
37 | + // 패딩 | |
38 | + private double padding_right; | |
39 | + | |
40 | + // 마진 | |
41 | + private double margin_bottom; | |
42 | + | |
43 | + // 패딩 | |
44 | + private double padding_bottom; | |
45 | + | |
46 | + // 생성자 | |
47 | + public PaddingAndMargin(){ | |
48 | + this.margin_top = 0; | |
49 | + this.padding_top = 0; | |
50 | + this.margin_left = 0; | |
51 | + this.padding_left = 0; | |
52 | + this.margin_right = 0; | |
53 | + this.padding_right = 0; | |
54 | + this.margin_bottom = 0; | |
55 | + this.padding_bottom = 0; | |
56 | + } | |
57 | + | |
58 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/stylesheet/vo/StyleSheet.java
... | ... | @@ -0,0 +1,44 @@ |
1 | +package com.takensoft.taken_bi_manager.common.stylesheet.vo; | |
2 | + | |
3 | + | |
4 | +import lombok.Getter; | |
5 | +import lombok.Setter; | |
6 | + | |
7 | +import java.util.ArrayList; | |
8 | +import java.util.List; | |
9 | + | |
10 | +/** | |
11 | + * @author 김성원 | |
12 | + * @since 2024.02.27 | |
13 | + * | |
14 | + * 레이아웃및 스타일 관련 처리 데이터 VO | |
15 | + */ | |
16 | +@Getter | |
17 | +@Setter | |
18 | +public class StyleSheet { | |
19 | + | |
20 | + // 스타일 시트 아이디 | |
21 | + private String stylesheet_id; | |
22 | + | |
23 | + // 폰트 스타일 리스트 | |
24 | + private FontStyle fontStyle; | |
25 | + | |
26 | + // 보더 스타일 | |
27 | + private BorderStyle borderStyle; | |
28 | + | |
29 | + // 백그라운드 스타일 | |
30 | + private Background_style background_style; | |
31 | + | |
32 | + // 패딩 | |
33 | + private PaddingAndMargin paddingAndMargin; | |
34 | + | |
35 | + // 생성자 | |
36 | + public StyleSheet(){ | |
37 | + // this.fontStyleList = new FontStyle<>(); | |
38 | + // this.borderStyle = new ArrayList<>(); | |
39 | + //this.BorderStyle.add(new BorderStyle()); | |
40 | + // this.background_style = new ArrayList<>(); | |
41 | + // this.paddingAndMargin = new ArrayList<>(); | |
42 | + } | |
43 | + | |
44 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/AsyncUtil.java
... | ... | @@ -0,0 +1,54 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | + | |
4 | +import com.takensoft.taken_bi_manager.common.util.reflection.ReflectionUtil; | |
5 | + | |
6 | +import java.util.concurrent.Callable; | |
7 | + | |
8 | +/* | |
9 | +public class AsyncUtil implements Runnable { | |
10 | +*/ | |
11 | +public class AsyncUtil implements Callable<Object> { | |
12 | + | |
13 | + String classFilePath, packageName, className, methodName; | |
14 | + Object[] paramValues; | |
15 | + Class<?>[] paramTypes; | |
16 | + | |
17 | + public AsyncUtil(String classFilePath, String packageName, String className, String methodName, Object[] paramValues, Class<?>[] paramTypes) { | |
18 | + this.classFilePath = classFilePath; | |
19 | + this.packageName = packageName; | |
20 | + this.className = className; | |
21 | + this.methodName = methodName; | |
22 | + this.paramValues = paramValues; | |
23 | + this.paramTypes = paramTypes; | |
24 | + } | |
25 | + | |
26 | + public AsyncUtil(String packageName, String className, String methodName, Object[] paramValues, Class<?>[] paramTypes) { | |
27 | + this.packageName = packageName; | |
28 | + this.className = className; | |
29 | + this.methodName = methodName; | |
30 | + this.paramValues = paramValues; | |
31 | + this.paramTypes = paramTypes; | |
32 | + } | |
33 | + | |
34 | + @Override | |
35 | + public Object call() throws Exception { | |
36 | + try { | |
37 | + // 객체 생성 및 메소드 실행 | |
38 | + Object clazz = ReflectionUtil.classAndBeanLoad(classFilePath, (packageName + "." + className)); | |
39 | + ReflectionUtil.invokeByMethodName(clazz, methodName, paramValues, paramTypes); | |
40 | + return null; | |
41 | + } catch (Exception e) { | |
42 | + throw new Exception(e); | |
43 | + } | |
44 | + } | |
45 | +/* | |
46 | + public void run () { | |
47 | + //객체 생성 | |
48 | + Object clazz = ReflectionUtil.classAndBeanLoad(classFilePath, (packageName + "." + className)); | |
49 | + //메서드 실행 | |
50 | + ReflectionUtil.invokeByMethodName(clazz, methodName, paramValues, paramTypes); | |
51 | + } | |
52 | +*/ | |
53 | + | |
54 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/AuthUtil.java
... | ... | @@ -0,0 +1,100 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | + | |
4 | +import org.slf4j.Logger; | |
5 | +import org.slf4j.LoggerFactory; | |
6 | + | |
7 | +import jakarta.servlet.http.HttpSession; | |
8 | + | |
9 | +import java.util.HashMap; | |
10 | + | |
11 | +public class AuthUtil { | |
12 | + | |
13 | + private static final Logger LOGGER = LoggerFactory.getLogger(AuthUtil.class); | |
14 | + | |
15 | + //Session에 등록된 Login User ID Key | |
16 | + public static final String LOGIN_USER_SESSION = "loginUsers"; | |
17 | + | |
18 | + //중복 로그인가능 여부 | |
19 | + public static final boolean IS_POSSIBLE_DUPLICATION_LOGIN = false; | |
20 | + | |
21 | + //Session Max 시간(초) | |
22 | + public static final int SESSION_MAX_TIME = 60*60*6;//6시간 | |
23 | + | |
24 | + public static HashMap<String, Object> getLoginUser () { | |
25 | + try { | |
26 | + //현재 client의 HttpSession 조회 | |
27 | + HttpSession session = CommonUtil.getHttpSession(false); | |
28 | + if(session == null || session.getAttribute(LOGIN_USER_SESSION) == null || ((HashMap<String, Object>) session.getAttribute(LOGIN_USER_SESSION)).get("user_id") == null) { | |
29 | + return null; | |
30 | + }else { | |
31 | + return (HashMap<String, Object>) session.getAttribute(LOGIN_USER_SESSION); | |
32 | + } | |
33 | + } catch(NullPointerException e) { | |
34 | + LOGGER.error(e.toString()); | |
35 | + | |
36 | + // e.printStackTrace(); | |
37 | + return null; | |
38 | + } | |
39 | + } | |
40 | + | |
41 | + public static String getLoginUserId () { | |
42 | + HashMap<String, Object> user = getLoginUser(); | |
43 | + if (user != null) { | |
44 | + return (String) user.get("user_id"); | |
45 | + } else { | |
46 | + return null; | |
47 | + } | |
48 | + } | |
49 | + public static HashMap<String, Object> getKey () { | |
50 | + try { | |
51 | + //현재 client의 HttpSession 조회 | |
52 | + HttpSession session = CommonUtil.getHttpSession(true); | |
53 | + if(session == null || session.getAttribute("key") == null || ((HashMap<String, Object>) session.getAttribute("key")).get("salt") == null) { | |
54 | + return null; | |
55 | + }else { | |
56 | + return ((HashMap<String, Object>) session.getAttribute("key")); | |
57 | + } | |
58 | + } catch(NullPointerException e) { | |
59 | + LOGGER.error(e.toString()); | |
60 | + return null; | |
61 | + } | |
62 | + } | |
63 | + | |
64 | + public static String getKeySaltKey () { | |
65 | + HashMap<String, Object> key = getKey(); | |
66 | + if (key != null ) { | |
67 | + if(key.get("salt") != null) { | |
68 | + return key.get("salt").toString(); | |
69 | + }else { | |
70 | + return null; | |
71 | + } | |
72 | + } else { | |
73 | + return null; | |
74 | + } | |
75 | + } | |
76 | + public static String getKeyIvtKey () { | |
77 | + HashMap<String, Object> key = getKey(); | |
78 | + if (key != null ) { | |
79 | + if(key != null) { | |
80 | + return key.get("iv").toString(); | |
81 | + }else { | |
82 | + return null; | |
83 | + } | |
84 | + } else { | |
85 | + return null; | |
86 | + } | |
87 | + } | |
88 | + public static String getKeyENC_KEY () { | |
89 | + HashMap<String, Object> key = getKey(); | |
90 | + if (key != null ) { | |
91 | + if(key.get("ENC_KEY") != null) { | |
92 | + return key.get("ENC_KEY").toString(); | |
93 | + }else{ | |
94 | + return null; | |
95 | + } | |
96 | + } else { | |
97 | + return null; | |
98 | + } | |
99 | + } | |
100 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/CommonUtil.java
... | ... | @@ -0,0 +1,803 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.io.IOException; | |
6 | +import java.lang.reflect.Field; | |
7 | +import java.lang.reflect.Modifier; | |
8 | +import java.math.BigDecimal; | |
9 | +import java.net.InetAddress; | |
10 | +import java.net.InetSocketAddress; | |
11 | +import java.net.Socket; | |
12 | +import java.net.UnknownHostException; | |
13 | +import java.text.SimpleDateFormat; | |
14 | +import java.util.ArrayList; | |
15 | +import java.util.Arrays; | |
16 | +import java.util.Collection; | |
17 | +import java.util.Date; | |
18 | +import java.util.HashMap; | |
19 | +import java.util.LinkedHashMap; | |
20 | +import java.util.List; | |
21 | +import java.util.Map; | |
22 | +import java.util.Set; | |
23 | +import java.util.UUID; | |
24 | + | |
25 | +import jakarta.servlet.http.HttpServletRequest; | |
26 | +import jakarta.servlet.http.HttpSession; | |
27 | + | |
28 | +import org.json.XML; | |
29 | +import org.json.simple.JSONArray; | |
30 | +import org.json.simple.JSONObject; | |
31 | +import org.springframework.web.context.request.RequestContextHolder; | |
32 | +import org.springframework.web.context.request.ServletRequestAttributes; | |
33 | + | |
34 | +import com.fasterxml.jackson.core.JsonParseException; | |
35 | +import com.fasterxml.jackson.core.type.TypeReference; | |
36 | +import com.fasterxml.jackson.databind.JsonMappingException; | |
37 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
38 | +import com.fasterxml.jackson.databind.SerializationFeature; | |
39 | +import com.takensoft.taken_bi_manager.user.member.vo.Member; | |
40 | + | |
41 | +public class CommonUtil { | |
42 | + | |
43 | + /** | |
44 | + * @author 최정우 | |
45 | + * @since 2019.12.11 | |
46 | + * | |
47 | + * 데이터의 표준화 사용 유무 | |
48 | + */ | |
49 | + private static boolean IS_USE_STANDARD = true; | |
50 | + | |
51 | + public static void setIsUseStandard (boolean isUseStandard) { | |
52 | + IS_USE_STANDARD = isUseStandard; | |
53 | + } | |
54 | + | |
55 | + public static boolean getIsUseStandard () { | |
56 | + return IS_USE_STANDARD; | |
57 | + } | |
58 | + | |
59 | + /** | |
60 | + * @author 최정우 | |
61 | + * @since 2019.11.13 | |
62 | + * | |
63 | + * 빈 문자열 검사 | |
64 | + */ | |
65 | + public static boolean isNull(Object obj) { | |
66 | + return obj == null; | |
67 | + } | |
68 | + | |
69 | + | |
70 | + /** | |
71 | + * @author 최정우 | |
72 | + * @since 2019.11.13 | |
73 | + * | |
74 | + * string to int check | |
75 | + */ | |
76 | + public static boolean isInt (String text) { | |
77 | + try { | |
78 | + Integer.parseInt(text); | |
79 | + return true; | |
80 | + } catch(NumberFormatException e) { | |
81 | + return false; | |
82 | + } | |
83 | + } | |
84 | + | |
85 | + /** | |
86 | + * @author 최정우 | |
87 | + * @since 2019.11.13 | |
88 | + * | |
89 | + * string to int check | |
90 | + */ | |
91 | + public static boolean isLong (String text) { | |
92 | + try { | |
93 | + Long.parseLong(text); | |
94 | + return true; | |
95 | + } catch(NumberFormatException e) { | |
96 | + return false; | |
97 | + } | |
98 | + } | |
99 | + | |
100 | + /** | |
101 | + * @author 최정우 | |
102 | + * @since 2019.11.13 | |
103 | + * | |
104 | + * string to double check | |
105 | + */ | |
106 | + public static boolean isDouble (String text) { | |
107 | + try { | |
108 | + Double.parseDouble(text); | |
109 | + return true; | |
110 | + } catch (NumberFormatException e) { | |
111 | + return false; | |
112 | + } catch (Exception e) { | |
113 | + return false; | |
114 | + } | |
115 | + } | |
116 | + | |
117 | + /** | |
118 | + * @author 최정우 | |
119 | + * @since 2020.01.08 | |
120 | + * | |
121 | + * object to int | |
122 | + */ | |
123 | + public static int parseInt (Object obj) { | |
124 | + try { | |
125 | + return Integer.parseInt(obj.toString()); | |
126 | + } catch(Exception e) { | |
127 | + return 0; | |
128 | + } | |
129 | + } | |
130 | + | |
131 | + /** | |
132 | + * @author 최정우 | |
133 | + * @since 2020.01.08 | |
134 | + * | |
135 | + * string to int | |
136 | + */ | |
137 | + public static int parseInt (String text) { | |
138 | + try { | |
139 | + return Integer.parseInt(text); | |
140 | + } catch(NumberFormatException e) { | |
141 | + return 0; | |
142 | + } | |
143 | + } | |
144 | + | |
145 | + /** | |
146 | + * @author 최정우 | |
147 | + * @since 2020.01.08 | |
148 | + * | |
149 | + * int to double | |
150 | + */ | |
151 | + public static long parseLong (int number) { | |
152 | + try { | |
153 | + return (long) number; | |
154 | + } catch(Exception e) { | |
155 | + return 0; | |
156 | + } | |
157 | + } | |
158 | + | |
159 | + /** | |
160 | + * @author 최정우 | |
161 | + * @since 2020.01.08 | |
162 | + * | |
163 | + * object to double | |
164 | + */ | |
165 | + public static long parseLong (String text) { | |
166 | + try { | |
167 | + return Long.parseLong(text); | |
168 | + } catch(Exception e) { | |
169 | + return 0; | |
170 | + } | |
171 | + } | |
172 | + | |
173 | + /** | |
174 | + * @author 최정우 | |
175 | + * @since 2020.01.08 | |
176 | + * | |
177 | + * object to double | |
178 | + */ | |
179 | + public static long parseLong (Object obj) { | |
180 | + try { | |
181 | + if (obj instanceof Integer) { | |
182 | + return (long) obj; | |
183 | + } else { | |
184 | + return Long.parseLong(obj.toString()); | |
185 | + } | |
186 | + } catch(Exception e) { | |
187 | + return 0; | |
188 | + } | |
189 | + } | |
190 | + | |
191 | + /** | |
192 | + * @author 최정우 | |
193 | + * @since 2020.01.08 | |
194 | + * | |
195 | + * int to double | |
196 | + */ | |
197 | + public static double parseDouble (int number) { | |
198 | + try { | |
199 | + return (double) number; | |
200 | + } catch(Exception e) { | |
201 | + return 0.0; | |
202 | + } | |
203 | + } | |
204 | + | |
205 | + /** | |
206 | + * @author 최정우 | |
207 | + * @since 2020.01.08 | |
208 | + * | |
209 | + * object to double | |
210 | + */ | |
211 | + public static double parseDouble (String text) { | |
212 | + try { | |
213 | + return Double.parseDouble(text); | |
214 | + } catch(Exception e) { | |
215 | + return 0.0; | |
216 | + } | |
217 | + } | |
218 | + | |
219 | + /** | |
220 | + * @author 최정우 | |
221 | + * @since 2020.01.08 | |
222 | + * | |
223 | + * object to double | |
224 | + */ | |
225 | + public static double parseDouble (Object obj) { | |
226 | + try { | |
227 | + if (obj instanceof Integer) { | |
228 | + return (double) obj; | |
229 | + } else { | |
230 | + return Double.parseDouble(obj.toString()); | |
231 | + } | |
232 | + } catch(Exception e) { | |
233 | + return 0.0; | |
234 | + } | |
235 | + } | |
236 | + | |
237 | + /** | |
238 | + * @author 최정우 | |
239 | + * @since 2019.11.13 | |
240 | + * | |
241 | + * 문자열의 모든 공백 제거 | |
242 | + */ | |
243 | + public static String allTrim(String text) { | |
244 | + return text.replaceAll("\\p{Z}", ""); | |
245 | + } | |
246 | + | |
247 | + /** | |
248 | + * @author 최정우 | |
249 | + * @since 2019.11.13 | |
250 | + * | |
251 | + * 문자열 앞뒤 공백 제거후, 문자열 사이에 존재하는 공백을 한개의 공백으로 치환 | |
252 | + * ex) " abcd efg hijk " => "abcd efg hijk" | |
253 | + */ | |
254 | + public static String normalizeSpace(String text) { | |
255 | + return text.trim().replaceAll("\\s+", " "); | |
256 | + } | |
257 | + | |
258 | + /** | |
259 | + * @author 최정우 | |
260 | + * @since 2019.11.13 | |
261 | + * | |
262 | + * 숫자 빼고 모든 문자 제거 | |
263 | + */ | |
264 | + public static String getOnlyNumber (String text) { | |
265 | + return text.replaceAll("[^0-9]", ""); | |
266 | + } | |
267 | + | |
268 | + /** | |
269 | + * @author 최정우 | |
270 | + * @since 2019.11.13 | |
271 | + * | |
272 | + * 문자 빼고 모든 숫자 제거 | |
273 | + */ | |
274 | + public static String getOnlyText (String text) { | |
275 | + return text.replaceAll("[0-9]", ""); | |
276 | + } | |
277 | + | |
278 | + /** | |
279 | + * @author 최정우 | |
280 | + * @since 2019.11.13 | |
281 | + * | |
282 | + * 특정 문자열 개수 check | |
283 | + */ | |
284 | + public static int getWordCount (String text, String word) { | |
285 | + int size = 0; | |
286 | + int fromIndex = -1; | |
287 | + while ((fromIndex = text.indexOf(word, fromIndex + 1)) >= 0) { | |
288 | + size++; | |
289 | + } | |
290 | + return size; | |
291 | + } | |
292 | + | |
293 | + /** | |
294 | + * @author 최정우 | |
295 | + * @since 2019.11.13 | |
296 | + * | |
297 | + * 문자열 to Date문자열 | |
298 | + */ | |
299 | + public static boolean isDate (String text) { | |
300 | + if (StringUtil.isEmpty(text) == true || StringUtil.isEmpty(getOnlyNumber(text)) == true || getOnlyNumber(text).length() < 6) { | |
301 | + return false; | |
302 | + } | |
303 | + | |
304 | + //공백을 제외한 문자얻기, 대문자로 치환 | |
305 | + String newText = allTrim(text).toUpperCase(); | |
306 | + | |
307 | + try { | |
308 | + //문자열의 날짜 패턴 생성 | |
309 | + String pattern = createDatePattern(newText); | |
310 | + if (pattern == null) { | |
311 | + return false; | |
312 | + } | |
313 | + | |
314 | + SimpleDateFormat newPattern = new SimpleDateFormat(pattern); | |
315 | + //문자열 날짜 형태로 변환 | |
316 | + newPattern.parse(newText); | |
317 | + return true; | |
318 | + } catch (Exception e) { | |
319 | + //e.printStackTrace(); | |
320 | + return false; | |
321 | + } | |
322 | + } | |
323 | + | |
324 | + /** | |
325 | + * @author 최정우 | |
326 | + * @since 2019.11.13 | |
327 | + * | |
328 | + * 문자열 to Date문자열 | |
329 | + */ | |
330 | + public static String parseDateText (String text) { | |
331 | + if (StringUtil.isEmpty(text) == true || StringUtil.isEmpty(getOnlyNumber(text)) == true || getOnlyNumber(text).length() < 6) { | |
332 | + return null; | |
333 | + } | |
334 | + | |
335 | + //공백을 제외한 문자얻기, 대문자로 치환 | |
336 | + String newText = allTrim(text).toUpperCase(); | |
337 | + | |
338 | + //문자열의 날짜 패턴 생성 | |
339 | + String pattern = createDatePattern(newText); | |
340 | + if (pattern == null) { | |
341 | + return null; | |
342 | + } | |
343 | + | |
344 | + Date date = null; | |
345 | + String dateText = null; | |
346 | + try { | |
347 | + SimpleDateFormat newPattern = new SimpleDateFormat(pattern); | |
348 | + | |
349 | + //문자열 날짜 형태로 변환 | |
350 | + date = newPattern.parse(newText); | |
351 | + | |
352 | + //DB에 저장할 날짜 패턴 | |
353 | + SimpleDateFormat defalutPattern = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |
354 | + dateText = defalutPattern.format(date); | |
355 | + } catch (Exception e) { | |
356 | + //e.printStackTrace(); | |
357 | + } | |
358 | + return dateText; | |
359 | + } | |
360 | + | |
361 | + public static <T> List<T> mapToList (Map<?, T> map) { | |
362 | + List<T> items = new ArrayList<T>(); | |
363 | + | |
364 | + if (map != null) { | |
365 | + for(Map.Entry<?, T> item : map.entrySet()) { | |
366 | + items.add(item.getValue()); | |
367 | + } | |
368 | + } | |
369 | + | |
370 | + return items; | |
371 | + } | |
372 | + | |
373 | + public static Map objectToMap(Object obj) { | |
374 | + if (obj != null) { | |
375 | + try { | |
376 | + return (Map) obj; | |
377 | + } catch (Exception e) { | |
378 | + return new HashMap(); | |
379 | + } | |
380 | + } else { | |
381 | + return new HashMap(); | |
382 | + } | |
383 | + } | |
384 | + | |
385 | + | |
386 | + /* | |
387 | + * 시간 타입 | |
388 | + * PM, AM | |
389 | + */ | |
390 | + public final static List<String> TIME_TYPES = Arrays.asList(new String[] {"AM", "PM", "오전", "오후"}); | |
391 | + | |
392 | + /* | |
393 | + * 날짜 포맷 패턴's | |
394 | + */ | |
395 | + public final static List<Character> DATE_PATTERNS = Arrays.asList(new Character[] {'y', 'M', 'd', 'H', 'm', 's'}); | |
396 | + | |
397 | + /* | |
398 | + * 날짜 포맷 패턴's의 최대 문자열 수 | |
399 | + */ | |
400 | + public final static List<Integer> DATE_PATTERNS_MAX_LENGTH = Arrays.asList(new Integer[] {4, 2, 2, 2, 2, 2}); | |
401 | + | |
402 | + /** | |
403 | + * @author 최정우 | |
404 | + * @since 2019.11.13 | |
405 | + * | |
406 | + * 문자열의 날짜 패턴 생성 | |
407 | + */ | |
408 | + public static String createDatePattern (String date) { | |
409 | + | |
410 | + List<Character> DATE_PATTERNS = Arrays.asList(new Character[] {'y', 'M', 'd', 'H', 'm', 's'}); | |
411 | + | |
412 | + //시간 표기가 (0~12 -> AM, PM사용)인지 (0~23)인지 확인 후, 날짜 포맷 패턴's에 있는 시간 패턴 변경 | |
413 | + int timeTypeFindIndex = -1; | |
414 | + for (int i = 0; i < TIME_TYPES.size(); i++) { | |
415 | + //("AM", "PM", "오전", "오후" 중 1개)가 포함된 단어가 있는지 확인, Index 위치를 담기(없으면 -1) | |
416 | + if ((timeTypeFindIndex = date.indexOf(TIME_TYPES.get(i))) > -1) { | |
417 | + //문자열에 포함된 ("AM", "PM", "오전", "오후" 중 1개) 삭제 | |
418 | + date = date.replaceAll(TIME_TYPES.get(i), ""); | |
419 | + //시간 패턴 변경 [H -> h] | |
420 | + DATE_PATTERNS.set(3, 'h'); | |
421 | + break; | |
422 | + } | |
423 | + } | |
424 | + | |
425 | + //숫자를 뺀 나머지 문자열 가지고오기 ex) "2020.08.03" -> ".." | |
426 | + //숫자를 뺀 나머지 문자열 가지고오기 ex) "2020.08.03 19:20:21" -> "..::" | |
427 | + final char[] separators = getOnlyText(date).toCharArray(); | |
428 | + | |
429 | + | |
430 | + | |
431 | + //사용할 최대 패턴 수 | |
432 | + int maxPatterSize = 0; | |
433 | + if (DATE_PATTERNS.size() <= separators.length) { | |
434 | + maxPatterSize = DATE_PATTERNS.size(); | |
435 | + } else { | |
436 | + maxPatterSize = separators.length; | |
437 | + } | |
438 | + | |
439 | + //구분자별 Index 위치's (사용할 최대 패턴 수 + 시작점:-1, 종료점:date문자열의 최종 길이) | |
440 | + List<Integer> sizeByPatterns = new ArrayList<Integer>(); | |
441 | + | |
442 | + | |
443 | + //구분자 별 Index 위치 파악 후, 앞에 있는 문자열의 수 찾은 후, 추가 (마지막 패턴 뒤에 있는 문자열을 따로 처리해줘야함) | |
444 | + int fromIndex = -1; | |
445 | + for (int i = 0; i < maxPatterSize; i++) { | |
446 | + //구분자 | |
447 | + char separator = separators[i]; | |
448 | + | |
449 | + //'현재 찾은 위치' : 이전에 찾은 위치(찾기 시작할 위치 => fromIndex) + 1 부터 찾기 시작함 | |
450 | + int currentFromIndex = date.indexOf(separator, fromIndex + 1); | |
451 | + | |
452 | + //현재 패턴의 문자열 수 = '현재 찾은 위치' - '이전에 찾은 위치' - 1 [추가] | |
453 | + sizeByPatterns.add(currentFromIndex - fromIndex - 1); | |
454 | + | |
455 | + //'현재 찾은 위치'는 '이전에 찾은 위치'가 됨 | |
456 | + fromIndex = currentFromIndex; | |
457 | + } | |
458 | + //마지막 패턴 뒤에 있는 문자열 = '문자열의 길이' - '마지막에 찾은 위치(이전에 찾은 위치)' - 1 [추가] | |
459 | + sizeByPatterns.add(date.length() - fromIndex - 1); | |
460 | + | |
461 | + | |
462 | + //패턴을 담을 변수 | |
463 | + StringBuilder pattern = new StringBuilder(); | |
464 | + | |
465 | + //DATE_PATTERS 순서 대로, 각 구분자 별 Index 위치 크기만큼 문자열에 패턴 삽입 + 구분자 삽입 | |
466 | + //마지막 전까지만 for문 돌림 | |
467 | + for (int i = 0, patternIndex = 0; i < sizeByPatterns.size() && patternIndex < DATE_PATTERNS.size(); i++, patternIndex++) { | |
468 | + | |
469 | + //패턴 추가 | |
470 | + int usingSize = 0; | |
471 | + for (int j = 0; j < sizeByPatterns.get(i); j++) { | |
472 | + if (j >= usingSize + DATE_PATTERNS_MAX_LENGTH.get(patternIndex)) { | |
473 | + usingSize += DATE_PATTERNS_MAX_LENGTH.get(patternIndex++); | |
474 | + | |
475 | + /*단 한개의 패턴이라도 '최대 문자열 수'를 넘어서면 -> '날짜 아님'*/ | |
476 | + if (i >= sizeByPatterns.size() || patternIndex >= DATE_PATTERNS.size()) { | |
477 | + return null; | |
478 | + } | |
479 | + } | |
480 | + | |
481 | + pattern.append(DATE_PATTERNS.get(patternIndex)); | |
482 | + } | |
483 | + | |
484 | + //날짜 구분자 추가 (마지막 구분자까지만) | |
485 | + if (i < separators.length) { | |
486 | + pattern.append(separators[i]); | |
487 | + } | |
488 | + | |
489 | + | |
490 | + } | |
491 | + | |
492 | + if (timeTypeFindIndex > -1) { | |
493 | + pattern.insert(timeTypeFindIndex, 'a'); | |
494 | + } | |
495 | + | |
496 | + if(!(pattern.toString().equals("-") || pattern.toString().equals("/") || pattern.toString().equals("."))){ | |
497 | + pattern = null; | |
498 | + } | |
499 | + | |
500 | + return pattern.toString(); | |
501 | + } | |
502 | + | |
503 | + | |
504 | + /** | |
505 | + * @author 최정우 | |
506 | + * @since 2020.01.26 | |
507 | + * | |
508 | + * ping 체크 | |
509 | + */ | |
510 | + public static boolean pingCheck (String ip) { | |
511 | + InetAddress inetAddress; | |
512 | + try { | |
513 | + inetAddress = InetAddress.getByName(ip); | |
514 | + return inetAddress.isReachable(1000); | |
515 | + } catch (UnknownHostException e) { | |
516 | + return false; | |
517 | + } catch (IOException e) { | |
518 | + return false; | |
519 | + } catch (Exception e) { | |
520 | + return false; | |
521 | + } | |
522 | + } | |
523 | + | |
524 | + /** | |
525 | + * @author 김성원 | |
526 | + * @since 2024.01.04 | |
527 | + * | |
528 | + * 접속 체크 (ip + port) | |
529 | + */ | |
530 | + public static boolean linkCheck(String ip, int port) { | |
531 | + Socket socket = new Socket(); | |
532 | + try { | |
533 | + socket.connect(new InetSocketAddress(ip, port), 1000); | |
534 | + boolean isConnect = socket.isConnected(); | |
535 | + socket.close(); | |
536 | + return isConnect; | |
537 | + } catch (UnknownHostException e) { | |
538 | + return false; | |
539 | + } catch (IOException e) { | |
540 | + return false; | |
541 | + } catch (Exception e) { | |
542 | + return false; | |
543 | + } | |
544 | + } | |
545 | + | |
546 | + | |
547 | + /** | |
548 | + * @author 최정우 | |
549 | + * @since 2019.12.09 | |
550 | + * | |
551 | + * 데이터 셋 목록 Convert LinkedHashMap<String, Object> to List<String> | |
552 | + */ | |
553 | + public static List<List<Object>> rowDataMapToList (List<LinkedHashMap<String, Object>> rowMapData) throws Exception { | |
554 | + List<List<Object>> rowData = new ArrayList<List<Object>>(); | |
555 | + for (int i = 0; i < rowMapData.size(); i++) { | |
556 | + List<Object> row = new ArrayList<Object>(); | |
557 | + LinkedHashMap<String, Object> mapdata = rowMapData.get(i); | |
558 | + | |
559 | + for( String key : mapdata.keySet() ){ | |
560 | + if (mapdata.get(key) == null) { | |
561 | + row.add("");//null값 대체 | |
562 | + } else { | |
563 | + row.add(mapdata.get(key).toString()); | |
564 | + } | |
565 | + } | |
566 | + rowData.add(row); | |
567 | + } | |
568 | + return rowData; | |
569 | + } | |
570 | + | |
571 | + /** | |
572 | + * @author 최정우 | |
573 | + * @since 2019.12.09 | |
574 | + * | |
575 | + * 데이터 셋 목록 Convert LinkedHashMap<String, Object> to List<String> | |
576 | + */ | |
577 | + public static List<List<Object>> rowDataMapToListOnject (List<LinkedHashMap<String, Object>> rowMapData) throws Exception { | |
578 | + List<List<Object>> rowData = new ArrayList<List<Object>>(); | |
579 | + for (int i = 0; i < rowMapData.size(); i++) { | |
580 | + List<Object> row = new ArrayList<Object>(); | |
581 | + LinkedHashMap<String, Object> mapdata = rowMapData.get(i); | |
582 | + for( String key : mapdata.keySet() ){ | |
583 | + if (mapdata.get(key) == null) { | |
584 | + row.add(null);//null값 대체 | |
585 | + } else { | |
586 | + row.add(mapdata.get(key)); | |
587 | + } | |
588 | + } | |
589 | + rowData.add(row); | |
590 | + } | |
591 | + return rowData; | |
592 | + } | |
593 | + | |
594 | + /** | |
595 | + * @author 최정우 | |
596 | + * @since 2020.01.26 | |
597 | + * | |
598 | + * 현재 client의 HttpServletRequest 조회 | |
599 | + */ | |
600 | + public static HttpServletRequest getHttpServletRequest () { | |
601 | + try { | |
602 | + ServletRequestAttributes servletRequestAttribute = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); | |
603 | + return servletRequestAttribute.getRequest(); | |
604 | + } catch (NullPointerException e) { | |
605 | + return null; | |
606 | + } | |
607 | + } | |
608 | + | |
609 | + | |
610 | + /** | |
611 | + * @author 최정우 | |
612 | + * @since 2020.01.26 | |
613 | + * | |
614 | + * 현재 client의 HttpSession 조회 | |
615 | + */ | |
616 | + public static HttpSession getHttpSession (boolean create) { | |
617 | + try { | |
618 | + HttpServletRequest request = getHttpServletRequest(); | |
619 | + if (request != null) { | |
620 | + return request.getSession(create); | |
621 | + } else { | |
622 | + return null; | |
623 | + } | |
624 | + } catch (NullPointerException e) { | |
625 | + return null; | |
626 | + } | |
627 | + } | |
628 | + | |
629 | + /** | |
630 | + * @author 김성원 | |
631 | + * @since 2024.01.10 | |
632 | + * | |
633 | + * 사용자 세션 정보 조회 | |
634 | + */ | |
635 | + public static HashMap<String, Object> getHttpSessionMember () { | |
636 | + try { | |
637 | + HttpServletRequest request = getHttpServletRequest(); | |
638 | + if(request.getSession().getAttribute(AuthUtil.LOGIN_USER_SESSION) != null) { | |
639 | + return (HashMap<String, Object>)request.getSession().getAttribute(AuthUtil.LOGIN_USER_SESSION); | |
640 | + }else { | |
641 | + return null; | |
642 | + } | |
643 | + } catch (NullPointerException e) { | |
644 | + return null; | |
645 | + } | |
646 | + } | |
647 | + | |
648 | + /** | |
649 | + * @author 최정우 | |
650 | + * @since 2020.01.26 | |
651 | + * | |
652 | + * HttpServletRequest를 활용한 Client IP 가지고오기 | |
653 | + * Header의 X-FORWARDED-FOR 값을 통해 IP 조회, 만약 Header에 X-FORWARDED-FOR가 없으면 getRemoteAddr() 이걸로 조회 | |
654 | + */ | |
655 | + public static String getClientIp () { | |
656 | + try { | |
657 | + HttpServletRequest request = getHttpServletRequest(); | |
658 | + if (null != request.getHeader("X-FORWARDED-FOR")) { | |
659 | + return request.getHeader("X-FORWARDED-FOR"); | |
660 | + } else { | |
661 | + return request.getRemoteAddr(); | |
662 | + } | |
663 | + } catch (NullPointerException e) { | |
664 | + return null; | |
665 | + } | |
666 | + } | |
667 | + | |
668 | + | |
669 | + | |
670 | + /** | |
671 | + * @author 최정우 | |
672 | + * @since 2019.12.09 | |
673 | + * | |
674 | + * JSONObject to Map<String, Object> | |
675 | + */ | |
676 | + public static Map<String, Object> jsonObjectToMap( JSONObject jsonObj ) { | |
677 | + Map<String, Object> map = null; | |
678 | + try { | |
679 | + map = new ObjectMapper().readValue(jsonObj.toJSONString(), Map.class) ; | |
680 | + | |
681 | + } catch (JsonParseException e) { | |
682 | + e.printStackTrace(); | |
683 | + } catch (JsonMappingException e) { | |
684 | + e.printStackTrace(); | |
685 | + } catch (IOException e) { | |
686 | + e.printStackTrace(); | |
687 | + } | |
688 | + return map; | |
689 | + } | |
690 | + | |
691 | + /** | |
692 | + * @author 최정우 | |
693 | + * @since 2019.12.09 | |
694 | + * | |
695 | + * JSONObject to List<Map<String, Object>> | |
696 | + */ | |
697 | + public static List<Map<String, Object>> jsonArrayToMap( JSONArray jsonObj ) { | |
698 | + List<Map<String, Object>> map = null; | |
699 | + try { | |
700 | + map = new ObjectMapper().readValue(jsonObj.toJSONString(), new TypeReference<List<Map<String, Object>>>(){}) ; | |
701 | + | |
702 | + } catch (JsonParseException e) { | |
703 | + e.printStackTrace(); | |
704 | + } catch (JsonMappingException e) { | |
705 | + e.printStackTrace(); | |
706 | + } catch (IOException e) { | |
707 | + e.printStackTrace(); | |
708 | + } | |
709 | + return map; | |
710 | + } | |
711 | + | |
712 | + /** | |
713 | + * @author 최정우 | |
714 | + * @since 2019.12.09 | |
715 | + * | |
716 | + * xmlStr to JsonStr | |
717 | + */ | |
718 | + public static String xmlStrToJsonStr(String xmlStr) throws Exception { | |
719 | + org.json.JSONObject jObject = XML.toJSONObject(xmlStr); | |
720 | + ObjectMapper mapper = new ObjectMapper(); | |
721 | + mapper.enable(SerializationFeature.INDENT_OUTPUT); | |
722 | + Object json = mapper.readValue(jObject.toString(), Object.class); | |
723 | + String output = mapper.writeValueAsString(json); | |
724 | + return output; | |
725 | + } | |
726 | + | |
727 | + | |
728 | + | |
729 | + /** | |
730 | + * @author 김성원 | |
731 | + * @since 2024.01.10 | |
732 | + * | |
733 | + * 데이터베이스 난수생성 | |
734 | + */ | |
735 | + public static String getRandKey(String prifix) { | |
736 | + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); | |
737 | + long timeInMillis =System.currentTimeMillis(); | |
738 | + Date timeInDate = new Date(timeInMillis); | |
739 | + return prifix+"_"+sdf.format(timeInDate)+UUID.randomUUID().toString().substring(0,5); | |
740 | + } | |
741 | + | |
742 | + /** | |
743 | + * @author 김성원 | |
744 | + * @since 2024.01.10 | |
745 | + * | |
746 | + * 로그인된 사용자 ID 조회 | |
747 | + */ | |
748 | + public static String getLoginUserId() { | |
749 | + String resultId = ""; | |
750 | + HashMap<String, Object> LoginUserInfo = new HashMap<>(); | |
751 | + HttpServletRequest request = CommonUtil.getHttpServletRequest(); | |
752 | + HttpSession session = request.getSession(false); | |
753 | + | |
754 | + if(session != null && session.getAttribute(AuthUtil.LOGIN_USER_SESSION) != null) { | |
755 | + LoginUserInfo = (HashMap<String, Object>)session.getAttribute(AuthUtil.LOGIN_USER_SESSION); | |
756 | + resultId = LoginUserInfo.get("user_id").toString(); | |
757 | + } | |
758 | + | |
759 | + return resultId; | |
760 | + } | |
761 | + | |
762 | + /** | |
763 | + * @author 김성원 | |
764 | + * @since 2024.01.10 | |
765 | + * | |
766 | + * 로그인된 사용자 ID 조회 | |
767 | + */ | |
768 | + public static String getLoginUserDeptCode() { | |
769 | + String resultId = ""; | |
770 | + HashMap<String, Object> LoginUserInfo = new HashMap<>(); | |
771 | + HttpServletRequest request = CommonUtil.getHttpServletRequest(); | |
772 | + HttpSession session = request.getSession(false); | |
773 | + | |
774 | + if(session != null && session.getAttribute(AuthUtil.LOGIN_USER_SESSION) != null) { | |
775 | + LoginUserInfo = (HashMap<String, Object>)session.getAttribute(AuthUtil.LOGIN_USER_SESSION); | |
776 | + Object deptCodeObj = LoginUserInfo.get("dept_code"); | |
777 | + resultId = (deptCodeObj != null) ? deptCodeObj.toString() : null; // null일 때 null 반환 | |
778 | + } | |
779 | + | |
780 | + return resultId; | |
781 | + } | |
782 | + | |
783 | + /** | |
784 | + * @author 김성원 | |
785 | + * @since 2024.01.10 | |
786 | + * | |
787 | + * 로그인된 사용자 권한 조회 | |
788 | + */ | |
789 | + public static List<String> getLoginUserAuth() { | |
790 | + List<String> authList = new ArrayList<>(); | |
791 | + HashMap<String, Object> LoginUserInfo = new HashMap<>(); | |
792 | + HttpServletRequest request = CommonUtil.getHttpServletRequest(); | |
793 | + HttpSession session = request.getSession(false); | |
794 | + if(session != null && session.getAttribute(AuthUtil.LOGIN_USER_SESSION) != null) { | |
795 | + LoginUserInfo = (HashMap<String, Object>)session.getAttribute(AuthUtil.LOGIN_USER_SESSION); | |
796 | + authList = (List<String>)LoginUserInfo.get("user_auth"); | |
797 | + } | |
798 | + return authList; | |
799 | + } | |
800 | + | |
801 | + | |
802 | + | |
803 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/CryptoUtil.java
... | ... | @@ -0,0 +1,221 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | + | |
4 | +import java.nio.ByteBuffer; | |
5 | +import java.nio.charset.StandardCharsets; | |
6 | +import java.util.Base64; | |
7 | +import java.util.Base64.Decoder; | |
8 | +import java.util.Base64.Encoder; | |
9 | +import java.util.HashMap; | |
10 | +import java.util.Map; | |
11 | + | |
12 | +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | |
13 | +import org.springframework.security.crypto.encrypt.AesBytesEncryptor; | |
14 | +import org.springframework.security.crypto.factory.PasswordEncoderFactories; | |
15 | +import org.springframework.security.crypto.password.DelegatingPasswordEncoder; | |
16 | +import org.springframework.security.crypto.password.PasswordEncoder; | |
17 | + | |
18 | +/** | |
19 | + * @author 김성원 | |
20 | + * @since 2024.01.02 | |
21 | + * | |
22 | + * 암호화 관련 클래스 | |
23 | + */ | |
24 | +public class CryptoUtil { | |
25 | + | |
26 | + | |
27 | + private final static String encoderKey = "bcrypt"; | |
28 | + private final static String secret = "takenbmsc!@#"; | |
29 | + private final static String salt = "70726574657374"; | |
30 | + | |
31 | + /** | |
32 | + * @author 김성원 | |
33 | + * @since 2024.01.09 | |
34 | + * | |
35 | + * 기본 단방향 엔코드 생성 | |
36 | + */ | |
37 | + public static PasswordEncoder createDelegatingPasswordEncoder() { | |
38 | + Map<String, PasswordEncoder> encoders = new HashMap<>(); | |
39 | + encoders.put(encoderKey, new BCryptPasswordEncoder()); | |
40 | + return new DelegatingPasswordEncoder(encoderKey, encoders); | |
41 | + } | |
42 | + | |
43 | + /** | |
44 | + * @author 김성원 | |
45 | + * @since 2024.01.09 | |
46 | + * | |
47 | + * 커스텀 key기반의 단방향 엔코드 생성 | |
48 | + */ | |
49 | + public static PasswordEncoder createDelegatingPasswordEncoder(String key) { | |
50 | + Map<String, PasswordEncoder> encoders = new HashMap<>(); | |
51 | + encoders.put(key, new BCryptPasswordEncoder()); | |
52 | + return new DelegatingPasswordEncoder(key, encoders); | |
53 | + } | |
54 | + | |
55 | + | |
56 | + /** | |
57 | + * @author 김성원 | |
58 | + * @since 2024.01.09 | |
59 | + * | |
60 | + * 기본 단방향 암호화 | |
61 | + */ | |
62 | + public static String PasswordEncoder(String data) { | |
63 | + | |
64 | + PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); | |
65 | + Encoder encoder = Base64.getEncoder(); | |
66 | + return encoder.encodeToString(passwordEncoder.encode(data).getBytes(StandardCharsets.UTF_8)) ; | |
67 | + } | |
68 | + | |
69 | + /** | |
70 | + * @author 김성원 | |
71 | + * @since 2024.01.09 | |
72 | + * | |
73 | + * 커스텀 key기반의 단방향 암호화 | |
74 | + */ | |
75 | + public static String PasswordEncoder(String key , String data) { | |
76 | + | |
77 | + if(StringUtil.isEmpty(data)) { | |
78 | + return data; | |
79 | + } | |
80 | + | |
81 | + PasswordEncoder passwordEncoder = createDelegatingPasswordEncoder(key); | |
82 | + | |
83 | + return passwordEncoder.encode(data); | |
84 | + } | |
85 | + | |
86 | + | |
87 | + | |
88 | + /** | |
89 | + * @author 김성원 | |
90 | + * @since 2024.01.09 | |
91 | + * | |
92 | + * 단방향 암호화 비교구문 | |
93 | + */ | |
94 | + public static boolean passwordMatch(String data, String checkData) { | |
95 | + | |
96 | + PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); | |
97 | + Decoder decoder = Base64.getDecoder(); | |
98 | + return passwordEncoder.matches(data,new String(decoder.decode(checkData), StandardCharsets.UTF_8) ); | |
99 | + | |
100 | + } | |
101 | + | |
102 | + | |
103 | + /** | |
104 | + * @author 김성원 | |
105 | + * @since 2024.01.09 | |
106 | + * | |
107 | + * 기본 key, salt 기반의 양방향 암호화 객체 생성 | |
108 | + */ | |
109 | + public static AesBytesEncryptor aesBytesEncryptor() { | |
110 | + return new AesBytesEncryptor("232323", salt); | |
111 | + } | |
112 | + | |
113 | + /** | |
114 | + * @author 김성원 | |
115 | + * @since 2024.01.09 | |
116 | + * | |
117 | + * 커스텀 key, salt 기반의 양방향 암호화 객체 생성 | |
118 | + */ | |
119 | + public static AesBytesEncryptor aesBytesEncryptor(String key, String salt) { | |
120 | + return new AesBytesEncryptor(key, salt); | |
121 | + | |
122 | + } | |
123 | + | |
124 | + /** | |
125 | + * @author 김성원 | |
126 | + * @since 2024.01.09 | |
127 | + * | |
128 | + * 기본 key, salt 기반의 양방향 암호화 | |
129 | + */ | |
130 | + public static String encryptData(String data) { | |
131 | + if(StringUtil.isEmpty(data)) { | |
132 | + return data; | |
133 | + } | |
134 | + AesBytesEncryptor bytesEncryptor = aesBytesEncryptor(); | |
135 | + byte[] encrypt = bytesEncryptor.encrypt(data.getBytes(StandardCharsets.UTF_8)); | |
136 | + Encoder encoder = Base64.getEncoder(); | |
137 | + return encoder.encodeToString(encrypt); | |
138 | + } | |
139 | + | |
140 | + /** | |
141 | + * @author 김성원 | |
142 | + * @since 2024.01.09 | |
143 | + * | |
144 | + * 커스텀 key, salt 기반의 양방향 암호화 | |
145 | + */ | |
146 | + public static String encryptData(String key, String salt, String data) { | |
147 | + if(StringUtil.isEmpty(data)) { | |
148 | + return data; | |
149 | + } | |
150 | + AesBytesEncryptor bytesEncryptor = aesBytesEncryptor(key, salt); | |
151 | + byte[] encrypt = bytesEncryptor.encrypt(data.getBytes(StandardCharsets.UTF_8)); | |
152 | + Encoder encoder = Base64.getEncoder(); | |
153 | + return encoder.encodeToString(encrypt); | |
154 | + } | |
155 | + | |
156 | + | |
157 | + | |
158 | + /** | |
159 | + * @author 김성원 | |
160 | + * @since 2024.01.09 | |
161 | + * | |
162 | + * 기본 key, salt 기반의 양방향 복호화 | |
163 | + */ | |
164 | + public static String decryptData(String data) { | |
165 | + if(StringUtil.isEmpty(data)) { | |
166 | + return data; | |
167 | + } | |
168 | + AesBytesEncryptor bytesEncryptor = aesBytesEncryptor(); | |
169 | + Decoder decoder = Base64.getDecoder(); | |
170 | + byte[] decrypt = bytesEncryptor.decrypt(decoder.decode(data)); | |
171 | + return new String(decrypt, StandardCharsets.UTF_8); | |
172 | + } | |
173 | + | |
174 | + /** | |
175 | + * @author 김성원 | |
176 | + * @since 2024.01.09 | |
177 | + * | |
178 | + * 커스텀 key, salt 기반의 양방향 복호화 | |
179 | + */ | |
180 | + public static String decryptData(String key, String salt, String data) { | |
181 | + if(StringUtil.isEmpty(data)) { | |
182 | + return data; | |
183 | + } | |
184 | + AesBytesEncryptor bytesEncryptor = aesBytesEncryptor(key, salt); | |
185 | + Decoder decoder = Base64.getDecoder(); | |
186 | + byte[] decrypt = bytesEncryptor.decrypt(decoder.decode(data)); | |
187 | + return new String(decrypt, StandardCharsets.UTF_8); | |
188 | + } | |
189 | + | |
190 | + | |
191 | + /** | |
192 | + * @author 김성원 | |
193 | + * @since 2024.01.09 | |
194 | + * | |
195 | + * * 바이트 스트링 변환 | |
196 | + */ | |
197 | + public static String byteArrayToString(byte[] bytes) { | |
198 | + StringBuilder sb = new StringBuilder(); | |
199 | + for (byte abyte :bytes){ | |
200 | + sb.append(abyte); | |
201 | + sb.append(" "); | |
202 | + } | |
203 | + return sb.toString(); | |
204 | + } | |
205 | + | |
206 | + /** | |
207 | + * @author 김성원 | |
208 | + * @since 2024.01.09 | |
209 | + * | |
210 | + * 스트링 바이트 변환 | |
211 | + */ | |
212 | + public static byte[] stringToByteArray(String byteString) { | |
213 | + String[] split = byteString.split("\\s"); | |
214 | + ByteBuffer buffer = ByteBuffer.allocate(split.length); | |
215 | + for (String s : split) { | |
216 | + buffer.put((byte) Integer.parseInt(s)); | |
217 | + } | |
218 | + return buffer.array(); | |
219 | + } | |
220 | + | |
221 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/HTTPUtil.java
... | ... | @@ -0,0 +1,344 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.io.BufferedReader; | |
6 | +import java.io.DataOutputStream; | |
7 | +import java.io.IOException; | |
8 | +import java.io.InputStreamReader; | |
9 | +import java.io.UnsupportedEncodingException; | |
10 | +import java.net.HttpURLConnection; | |
11 | +import java.net.MalformedURLException; | |
12 | +import java.net.URL; | |
13 | +import java.net.URLEncoder; | |
14 | +import java.sql.Timestamp; | |
15 | +import java.text.SimpleDateFormat; | |
16 | +import java.util.Calendar; | |
17 | +import java.util.List; | |
18 | +import java.util.Locale; | |
19 | +import java.util.Map; | |
20 | + | |
21 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ApiParam; | |
22 | + | |
23 | + | |
24 | +/** | |
25 | + * @author 최정우 | |
26 | + * @since 2020.07.21 | |
27 | + * | |
28 | + * 데이터 수집 - HTTP통신 관련 Util 입니다. | |
29 | + */ | |
30 | +public class HTTPUtil { | |
31 | + | |
32 | + /** | |
33 | + * @author 최정우 | |
34 | + * @throws Exception | |
35 | + * @since 2020.07.21 | |
36 | + * | |
37 | + * [GET] HTTP 통신 | |
38 | + */ | |
39 | + public synchronized String HttpGetConnection (String urlText, Map<String, Object> parameter) { | |
40 | + StringBuffer response = new StringBuffer(); | |
41 | + | |
42 | + URL url = null; | |
43 | + try { | |
44 | + if (parameter.isEmpty() == false) { | |
45 | + urlText += "?" + createUrlQuery(parameter, "UTF-8"); | |
46 | + } | |
47 | + url = new URL(urlText); | |
48 | + } catch (MalformedURLException e) { | |
49 | + // TODO Auto-generated catch block | |
50 | + e.printStackTrace(); | |
51 | + } | |
52 | + | |
53 | + HttpURLConnection httpCon = null; | |
54 | + try { | |
55 | + | |
56 | + /* Connection */ | |
57 | + httpCon = (HttpURLConnection) url.openConnection(); | |
58 | + httpCon.setRequestMethod("GET"); | |
59 | + httpCon.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"); | |
60 | + httpCon.setConnectTimeout(1000 * 60);//http통신 최대 커넥션 시간(1분) | |
61 | + httpCon.setReadTimeout(1000 * 60);//http통신 커넥션 이후, 데이터를 받아오는데 걸리는 최대 시간(1분) | |
62 | + httpCon.setDoInput(true);//받아올 데이터가 있을 때, 사용 | |
63 | + | |
64 | + //HTTP Request 결과 코드 | |
65 | + int responseCode = httpCon.getResponseCode(); | |
66 | + if (responseCode == 200) { | |
67 | + //Response 결과 데이터 받기 | |
68 | + BufferedReader input = new BufferedReader(new InputStreamReader(httpCon.getInputStream(), "UTF-8")); | |
69 | + | |
70 | + //Response 결과 데이터를 문자열로 만들기 | |
71 | + String result = null; | |
72 | + while ((result = input.readLine()) != null) { | |
73 | + response.append(result); | |
74 | + } | |
75 | + | |
76 | + //InputStream, BufferedReader 종료 | |
77 | + input.close(); | |
78 | + | |
79 | + //HTTP Connection 종료 | |
80 | + httpCon.disconnect(); | |
81 | + | |
82 | + } else { | |
83 | + | |
84 | + } | |
85 | + | |
86 | + } catch (Exception e) { | |
87 | + e.printStackTrace(); | |
88 | + } | |
89 | + | |
90 | + //문자열로된 Response 결과 return | |
91 | + return response.toString(); | |
92 | + } | |
93 | + | |
94 | + /** | |
95 | + * @author 최정우 | |
96 | + * @throws Exception | |
97 | + * @since 2020.07.21 | |
98 | + * | |
99 | + * [POST] HTTP 통신 | |
100 | + */ | |
101 | + public synchronized String HttpPostConnection (String urlText, Map<String, Object> parameter) { | |
102 | + StringBuffer response = new StringBuffer(); | |
103 | + | |
104 | + URL url = null; | |
105 | + try { | |
106 | + url = new URL(urlText); | |
107 | + } catch (MalformedURLException e) { | |
108 | + // TODO Auto-generated catch block | |
109 | + e.printStackTrace(); | |
110 | + } | |
111 | + | |
112 | + HttpURLConnection httpCon = null; | |
113 | + try { | |
114 | + /* Connection */ | |
115 | + httpCon = (HttpURLConnection) url.openConnection(); | |
116 | + httpCon.setRequestMethod("POST"); | |
117 | + httpCon.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"); | |
118 | + httpCon.setConnectTimeout(1000 * 60);//http통신 최대 커넥션 시간(1분) | |
119 | + httpCon.setReadTimeout(1000 * 60);//http통신 커넥션 이후, 데이터를 받아오는데 걸리는 최대 시간(1분) | |
120 | + httpCon.setDoInput(true);//받아올 데이터가 있을 때, 사용 | |
121 | + | |
122 | + //보낼 파라메터 데이터가 있을 때 | |
123 | + if (parameter.isEmpty() == false) { | |
124 | + String dataQuery = createUrlQuery(parameter, null); | |
125 | + | |
126 | + httpCon.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//보낼 데이터의 형태 | |
127 | + httpCon.setRequestProperty("Content-Length", String.valueOf(dataQuery.length())); | |
128 | + httpCon.setDoOutput(true); | |
129 | + | |
130 | + DataOutputStream wr = new DataOutputStream(httpCon.getOutputStream()); | |
131 | + wr.writeBytes(dataQuery); | |
132 | + wr.flush(); | |
133 | + wr.close(); | |
134 | + } | |
135 | + | |
136 | + //HTTP Request 결과 코드 | |
137 | + int responseCode = httpCon.getResponseCode(); | |
138 | + if (responseCode == 200) { | |
139 | + //Response 결과 데이터 받기 | |
140 | + BufferedReader input = new BufferedReader(new InputStreamReader(httpCon.getInputStream())); | |
141 | + | |
142 | + //Response 결과 데이터를 문자열로 만들기 | |
143 | + String result = null; | |
144 | + while ((result = input.readLine()) != null) { | |
145 | + response.append(result); | |
146 | + } | |
147 | + | |
148 | + //InputStream, BufferedReader 종료 | |
149 | + input.close(); | |
150 | + | |
151 | + //HTTP Connection 종료 | |
152 | + httpCon.disconnect(); | |
153 | + } else { | |
154 | + | |
155 | + } | |
156 | + | |
157 | + } catch (IOException e) { | |
158 | + // TODO Auto-generated catch block | |
159 | + e.printStackTrace(); | |
160 | + } | |
161 | + | |
162 | + //문자열로된 Response 결과 return | |
163 | + return response.toString(); | |
164 | + } | |
165 | + | |
166 | + /** | |
167 | + * @author 최정우 | |
168 | + * @throws Exception | |
169 | + * @since 2020.07.21 | |
170 | + * | |
171 | + * 파라메터 데이터를 HTTP통신을 위한 문자열로 변환시켜주는 메서드 | |
172 | + * Map -> String | |
173 | + */ | |
174 | + public String createUrlQuery (Map<String, Object> parameter, String incoding) { | |
175 | + if (parameter.isEmpty() == true) { | |
176 | + return ""; | |
177 | + } else { | |
178 | + StringBuilder query = new StringBuilder(); | |
179 | + for(Map.Entry<String,Object> param : parameter.entrySet()) { | |
180 | + try { | |
181 | + if(query.length() > 0) { | |
182 | + query.append('&'); | |
183 | + } | |
184 | + | |
185 | + if (StringUtil.isEmpty(incoding) == true) { | |
186 | + query.append(param.getKey()); | |
187 | + query.append('='); | |
188 | + query.append(param.getValue()); | |
189 | + } else { | |
190 | + query.append(URLEncoder.encode(param.getKey(), incoding)); | |
191 | + query.append('='); | |
192 | + query.append(URLEncoder.encode(String.valueOf(param.getValue()), incoding)); | |
193 | + } | |
194 | + | |
195 | + } catch (UnsupportedEncodingException e) { | |
196 | + e.printStackTrace(); | |
197 | + } | |
198 | + } | |
199 | + | |
200 | + return query.toString(); | |
201 | + } | |
202 | + } | |
203 | + | |
204 | + /** | |
205 | + * @author 최정우 | |
206 | + * @throws Exception | |
207 | + * @since 2020.07.21 | |
208 | + * | |
209 | + * [GET] HTTP 통신 | |
210 | + */ | |
211 | + public synchronized String HttpGetConnectionApi (String urlText, List<ApiParam> parameter) { | |
212 | + StringBuffer response = new StringBuffer(); | |
213 | + | |
214 | + URL url = null; | |
215 | + try { | |
216 | + if (parameter.isEmpty() == false) { | |
217 | + urlText += "?" + createUrlQueryApi(parameter, "UTF-8"); | |
218 | + } | |
219 | + url = new URL(urlText); | |
220 | + } catch (MalformedURLException e) { | |
221 | + // TODO Auto-generated catch block | |
222 | + e.printStackTrace(); | |
223 | + } | |
224 | + | |
225 | + HttpURLConnection httpCon = null; | |
226 | + try { | |
227 | + | |
228 | + /* Connection */ | |
229 | + httpCon = (HttpURLConnection) url.openConnection(); | |
230 | + httpCon.setRequestMethod("GET"); | |
231 | + httpCon.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"); | |
232 | + httpCon.setConnectTimeout(1000 * 60);//http통신 최대 커넥션 시간(1분) | |
233 | + httpCon.setReadTimeout(1000 * 60);//http통신 커넥션 이후, 데이터를 받아오는데 걸리는 최대 시간(1분) | |
234 | + httpCon.setDoInput(true);//받아올 데이터가 있을 때, 사용 | |
235 | + | |
236 | + //HTTP Request 결과 코드 | |
237 | + int responseCode = httpCon.getResponseCode(); | |
238 | + if (responseCode == 200) { | |
239 | + //Response 결과 데이터 받기 | |
240 | + BufferedReader input = new BufferedReader(new InputStreamReader(httpCon.getInputStream(), "UTF-8")); | |
241 | + | |
242 | + //Response 결과 데이터를 문자열로 만들기 | |
243 | + String result = null; | |
244 | + while ((result = input.readLine()) != null) { | |
245 | + response.append(result); | |
246 | + } | |
247 | + | |
248 | + //InputStream, BufferedReader 종료 | |
249 | + input.close(); | |
250 | + | |
251 | + //HTTP Connection 종료 | |
252 | + httpCon.disconnect(); | |
253 | + | |
254 | + } else { | |
255 | + | |
256 | + } | |
257 | + | |
258 | + } catch (Exception e) { | |
259 | + e.printStackTrace(); | |
260 | + } | |
261 | + | |
262 | + //문자열로된 Response 결과 return | |
263 | + return response.toString(); | |
264 | + } | |
265 | + | |
266 | + /** | |
267 | + * @author 최정우 | |
268 | + * @throws Exception | |
269 | + * @since 2020.07.21 | |
270 | + * | |
271 | + * 파라메터 데이터를 HTTP통신을 위한 문자열로 변환시켜주는 메서드 | |
272 | + * Map -> String | |
273 | + */ | |
274 | + public String createUrlQueryApi (List<ApiParam> parameter, String incoding) { | |
275 | + if (parameter.isEmpty() == true) { | |
276 | + return ""; | |
277 | + } else { | |
278 | + | |
279 | + | |
280 | + StringBuilder query = new StringBuilder(); | |
281 | + for(ApiParam param : parameter) { | |
282 | + try { | |
283 | + | |
284 | + // 날짜 변경 처리 | |
285 | + if(param.isDateForm() == true) { | |
286 | + param.setValue(getTodayaddMonth(param.getValue().toString(), param.getAddMonth())); | |
287 | + } | |
288 | + | |
289 | + | |
290 | + if(query.length() > 0) { | |
291 | + query.append('&'); | |
292 | + } | |
293 | + | |
294 | + if (StringUtil.isEmpty(incoding) == true) { | |
295 | + query.append(param.getKey()); | |
296 | + query.append('='); | |
297 | + query.append(param.getValue()); | |
298 | + } else { | |
299 | + query.append(URLEncoder.encode(param.getKey(), incoding)); | |
300 | + query.append('='); | |
301 | + if(param.isDisableDecode()) { | |
302 | + query.append(param.getValue()); | |
303 | + }else { | |
304 | + query.append(URLEncoder.encode(String.valueOf(param.getValue()), incoding)); | |
305 | + } | |
306 | + | |
307 | + } | |
308 | + | |
309 | + | |
310 | + } catch (UnsupportedEncodingException e) { | |
311 | + e.printStackTrace(); | |
312 | + } | |
313 | + } | |
314 | + | |
315 | + return query.toString(); | |
316 | + } | |
317 | + } | |
318 | + /** | |
319 | + * @author 김성원 | |
320 | + * @since 2019.11.13 | |
321 | + * | |
322 | + * 현재날짜(년,월,일)에 특정 개월수 + - | |
323 | + */ | |
324 | + public static String getTodayaddMonth(String pattern, int month) { | |
325 | + String defaultPattern = "yyyy-MM-dd"; | |
326 | + // 수정된 코드 | |
327 | + if (pattern == null || pattern.isEmpty()) { | |
328 | + pattern = defaultPattern; | |
329 | + } | |
330 | + | |
331 | + SimpleDateFormat dateFormat = null; | |
332 | + try { | |
333 | + dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
334 | + } catch (Exception e) { | |
335 | + dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA); | |
336 | + } | |
337 | + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); | |
338 | + Calendar cal = Calendar.getInstance(); | |
339 | + cal.add(Calendar.MONTH, month); | |
340 | + | |
341 | + return dateFormat.format(cal.getTime()); | |
342 | + } | |
343 | + | |
344 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/PaginationSupport.java
... | ... | @@ -0,0 +1,32 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | +/** | |
4 | + * 페이징 지원 객체 입니다. | |
5 | + * | |
6 | + * @author 서영석 | |
7 | + * @since 2023.10.24 | |
8 | + */ | |
9 | +public class PaginationSupport { | |
10 | + | |
11 | + //한 페이지당 보여질 데이터 개수 (Default) | |
12 | + private final static int PER_PAGE = 10; | |
13 | + | |
14 | + /** | |
15 | + * @author 서영석 | |
16 | + * @since 2023.10.24 | |
17 | + * 내용 : PostgreSQL 데이터 | |
18 | + */ | |
19 | + public static int pagingRowIndexForPostgreSql (int currentPage) { | |
20 | + return pagingRowIndexForPostgreSql(currentPage, PER_PAGE); | |
21 | + } | |
22 | + /** | |
23 | + * @author 서영석 | |
24 | + * @since 2023.10.24 | |
25 | + * 내용 : PostgreSQL 데이터 | |
26 | + */ | |
27 | + public static int pagingRowIndexForPostgreSql (int currentPage, int perPage) { | |
28 | + int startIndex = 0; | |
29 | + startIndex = (currentPage - 1) * perPage; | |
30 | + return startIndex; | |
31 | + } | |
32 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/SesssionEventListener.java
... | ... | @@ -0,0 +1,281 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | + | |
4 | +import org.slf4j.Logger; | |
5 | +import org.slf4j.LoggerFactory; | |
6 | + | |
7 | +import jakarta.servlet.annotation.WebListener; | |
8 | +import jakarta.servlet.http.HttpSession; | |
9 | +import jakarta.servlet.http.HttpSessionEvent; | |
10 | +import jakarta.servlet.http.HttpSessionListener; | |
11 | +import java.security.NoSuchAlgorithmException; | |
12 | +import java.security.SecureRandom; | |
13 | +import java.util.*; | |
14 | +import java.util.concurrent.ConcurrentHashMap; | |
15 | + | |
16 | +/** | |
17 | + * @author 서영석 | |
18 | + * @since 2023.05.31 | |
19 | + * | |
20 | + * Custom session 저장소를 만들어 놓고 | |
21 | + * Tomcat이 관리하는 session 생성 또는 소멸시, 발생하는 이벤트를 활용하여 (HttpSessionListener를 통해 이벤트를 받을 수 있음) | |
22 | + * Custom session 저장소에 추가, 삭제를 통해 | |
23 | + * session을 적절히 controll 하기위한 목적을 가진 Class 입니다. | |
24 | + */ | |
25 | +@WebListener | |
26 | +public class SesssionEventListener implements HttpSessionListener { | |
27 | + | |
28 | + private static final Logger LOGGER = LoggerFactory.getLogger(SesssionEventListener.class); | |
29 | + | |
30 | + //싱글턴패턴 사용을 위한 클래스변수 | |
31 | + public static SesssionEventListener sesssionEventListener = null; | |
32 | + | |
33 | + //싱글턴패턴으로 객체 생성 후 리턴. | |
34 | + public static synchronized SesssionEventListener getInstance() { | |
35 | + if(sesssionEventListener == null) { | |
36 | + sesssionEventListener = new SesssionEventListener(); | |
37 | + } | |
38 | + return sesssionEventListener; | |
39 | + } | |
40 | + | |
41 | + /** | |
42 | + * Custom session 저장소 (tomcat이 관리하고있는 실제 session저장소는 아님) 목록 | |
43 | + * ConcurrentHashMap을 사용하는 이유 : | |
44 | + * HashMap은 Thread Safe 하지 않기 때문에 싱글턴 패턴에서 해당 session 저장소를 사용하기 위해서는 Thread Safe 한 ConcurrentHashMap를 사용 | |
45 | + * HashTable도 Thread Safe 하지만, 읽기 쓰기 둘다 한개의 Thread만 접근 가능함 | |
46 | + * ConcurrentHashMap은 쓰기에서한 한개의 Tread만 접근 가능하도록 해놓음 (읽기는 여러개의 쓰레드에서 동시 접근 가능) | |
47 | + */ | |
48 | + private static final Map<String, HttpSession> sessions = new ConcurrentHashMap<>(); | |
49 | + | |
50 | + /** | |
51 | + * @author 서영석 | |
52 | + * @since 2023.05.31 | |
53 | + * | |
54 | + * @param userId : 사용자(회원) ID | |
55 | + * | |
56 | + * userId와 동일한 로그인 session을 가진 session ID 목록 조회 | |
57 | + */ | |
58 | + public synchronized static List<String> duplicationLoginSessionIdSelectListByUserId (String userId) { | |
59 | + List<String> result = new ArrayList<>(); | |
60 | + try { | |
61 | + //Custom session 저장소에서 session ID는 다르지만 userId가 같은게 존재하는지 확인 | |
62 | + for (String key : sessions.keySet()) { | |
63 | + HttpSession session = sessions.get(key); | |
64 | + if (session == null || session.getAttribute(AuthUtil.LOGIN_USER_SESSION) == null) { | |
65 | + //세션이 존재하고, 로그인 정보가 없으면 continue; | |
66 | + continue; | |
67 | + } else { | |
68 | + //로그인 정보가 있으면 -> 중복 확인 | |
69 | + HashMap<String, Object> loginUser = (HashMap<String, Object>) session.getAttribute(AuthUtil.LOGIN_USER_SESSION); | |
70 | + String loginUserId = (String) loginUser.get("user_id"); | |
71 | + | |
72 | + /** 사용자(회원) ID와 동일한 로그인 정보 일 시 -> add **/ | |
73 | + if (userId.equals(loginUserId) == true) { | |
74 | + result.add(session.getId()); | |
75 | + } else { | |
76 | + //동일한 로그인 정보가 아니면 -> continue; | |
77 | + continue; | |
78 | + } | |
79 | + } | |
80 | + } | |
81 | + } catch (NullPointerException e) { | |
82 | + LOGGER.error(e.toString()); | |
83 | + } | |
84 | + | |
85 | + return result; | |
86 | + } | |
87 | + | |
88 | + | |
89 | + /** | |
90 | + * @author 서영석 | |
91 | + * @since 2023.05.31 | |
92 | + * | |
93 | + * 현재 client의 정보와 중복된 로그인 session ID 목록 조회 | |
94 | + * | |
95 | + * 현재 User의 세션과 Custom session 저장소에 저장된 session 중 | |
96 | + * session ID는 다르지만 userId가 같은 session List return | |
97 | + */ | |
98 | + public synchronized static List<String> duplicationLoginSessionIdSelectList () { | |
99 | + List<String> result = new ArrayList<>(); | |
100 | + | |
101 | + try { | |
102 | + //현재 사용자의 session | |
103 | + HttpSession currentUserSession = CommonUtil.getHttpSession(false); | |
104 | + //현재 사용자의 session이 존재하고, 로그인 정보가 있을 때 | |
105 | + if (currentUserSession != null && currentUserSession.getAttribute(AuthUtil.LOGIN_USER_SESSION) == null) { | |
106 | + //현재 사용자의 로그인 정보 | |
107 | + HashMap<String, Object> currentLoginUser = (HashMap<String, Object>) currentUserSession.getAttribute(AuthUtil.LOGIN_USER_SESSION); | |
108 | + String currentLoginUserId = (String) currentLoginUser.get("user_id"); | |
109 | + | |
110 | + //Custom session 저장소에서 session ID는 다르지만 userId가 같은게 존재하는지 확인 | |
111 | + for (String key : sessions.keySet()) { | |
112 | + HttpSession session = sessions.get(key); | |
113 | + if (session == null || session.getAttribute(AuthUtil.LOGIN_USER_SESSION) == null) { | |
114 | + //세션이 존재하고, 로그인 정보가 없으면 continue; | |
115 | + continue; | |
116 | + } else if (currentUserSession.getId().equals(session.getId()) == true) { | |
117 | + //동일한 세션 ID이면 continue; | |
118 | + continue; | |
119 | + } else { | |
120 | + //로그인 정보가 있으면 -> 중복 확인 | |
121 | + HashMap<String, Object> duplicationLoginUser = (HashMap<String, Object>) session.getAttribute(AuthUtil.LOGIN_USER_SESSION); | |
122 | + String duplicationLoginUserId = (String) duplicationLoginUser.get("user_id"); | |
123 | + | |
124 | + /** 동일한 로그인 정보 일 시 -> add **/ | |
125 | + if (currentLoginUserId.equals(duplicationLoginUserId) == true) { | |
126 | + result.add(session.getId()); | |
127 | + } else { | |
128 | + //동일한 로그인 정보가 아니면 -> continue; | |
129 | + continue; | |
130 | + } | |
131 | + } | |
132 | + } | |
133 | + } | |
134 | + } catch (NullPointerException e) { | |
135 | + LOGGER.error(e.toString()); | |
136 | + } | |
137 | + | |
138 | + return result; | |
139 | + } | |
140 | + | |
141 | + /** | |
142 | + * @author 서영석 | |
143 | + * @since 2023.05.31 | |
144 | + * | |
145 | + * @param userId : 사용자(회원) ID | |
146 | + * | |
147 | + * userId와 동일한 로그인 session을 가진 session ID 목록 삭제 | |
148 | + */ | |
149 | + public static int duplicationLoginSessionDeleteByUserId (String userId) { | |
150 | + int result = 0; | |
151 | + try { | |
152 | + List<String> sessionIds = duplicationLoginSessionIdSelectListByUserId(userId); | |
153 | + for (int i = 0; i < sessionIds.size(); i++) { | |
154 | + //Custom session 저장소에서 session 무효화 시키기 | |
155 | + sessions.get(sessionIds.get(i)).invalidate(); | |
156 | + //Custom session 저장소에서 session 삭제 | |
157 | + sessions.remove(sessionIds.get(i)); | |
158 | + } | |
159 | + } catch (NullPointerException e) { | |
160 | + LOGGER.error(e.toString()); | |
161 | + } | |
162 | + return result; | |
163 | + } | |
164 | + | |
165 | + /** | |
166 | + * @author 서영석 | |
167 | + * @since 2023.05.31 | |
168 | + * | |
169 | + * 현재 client의 정보와 중복된 로그인 session 전부 무효화 시키기 (완전 삭제는 못시킴) | |
170 | + */ | |
171 | + public static int duplicationLoginSessionDeleteAll () { | |
172 | + int result = 0; | |
173 | + try { | |
174 | + List<String> sessionIds = duplicationLoginSessionIdSelectList(); | |
175 | + for (int i = 0; i < sessionIds.size(); i++) { | |
176 | + //Custom session 저장소에서 session 무효화 시키기 | |
177 | + sessions.get(sessionIds.get(i)).invalidate(); | |
178 | + //Custom session 저장소에서 session 삭제 | |
179 | + sessions.remove(sessionIds.get(i)); | |
180 | + } | |
181 | + } catch (NullPointerException e) { | |
182 | + LOGGER.error(e.toString()); | |
183 | + } | |
184 | + return result; | |
185 | + } | |
186 | + | |
187 | + //난수생성 | |
188 | + public static String generateRandomHex(int length) { | |
189 | + SecureRandom random = new SecureRandom(); | |
190 | + byte[] randomBytes = new byte[length / 2]; // 16진수 문자열의 길이에 맞게 바이트 배열 크기를 조절 | |
191 | + | |
192 | + random.nextBytes(randomBytes); | |
193 | + | |
194 | + // 바이트 배열을 16진수 문자열로 변환 | |
195 | + StringBuilder hexStringBuilder = new StringBuilder(); | |
196 | + for (byte b : randomBytes) { | |
197 | + hexStringBuilder.append(String.format("%02x", b)); | |
198 | + } | |
199 | + | |
200 | + return hexStringBuilder.toString(); | |
201 | + } | |
202 | + | |
203 | + /** | |
204 | + * HttpSessionListener Interface로 부터 상속 받은 메소드 | |
205 | + * | |
206 | + * tomcat에서 session이 생성되었을 때(session timeout), 발생하는 이벤트 | |
207 | + * @param target : session 이벤트(생성) 객체 | |
208 | + * | |
209 | + * session 생성 이벤트가 발생하면 Custom session 저장소(sessions)에 해당 session ID 값을 Key로 잡고 저장 | |
210 | + * (※ Default로 session에 현재 Client의 IP를 넣어줌) | |
211 | + */ | |
212 | + @Override | |
213 | + public void sessionCreated(HttpSessionEvent target) { | |
214 | + int i = 1; | |
215 | + for (String key : sessions.keySet()) { | |
216 | + HttpSession hs = sessions.get(key); | |
217 | + } | |
218 | + | |
219 | + // session에 key(salt) 값 넣기 시작 | |
220 | + HashMap<String, Object> key = new HashMap<String, Object>(); | |
221 | + | |
222 | + // "SHA1PRNG"은 알고리즘 이름 | |
223 | +// SecureRandom random = null; | |
224 | +// try { | |
225 | +// random = SecureRandom.getInstance("SHA1PRNG"); | |
226 | +// } catch (NoSuchAlgorithmException e) { | |
227 | +// e.printStackTrace(); | |
228 | +// } | |
229 | +// SecureRandom random = new SecureRandom(); | |
230 | +// | |
231 | +// byte[] saltBytes = new byte[24]; | |
232 | +// byte[] encKeyBytes = new byte[24]; | |
233 | +// byte[] ivBytes = new byte[24]; | |
234 | +// random.nextBytes(saltBytes); | |
235 | +// random.nextBytes(encKeyBytes); | |
236 | +// random.nextBytes(ivBytes); | |
237 | + //SALT 생성 | |
238 | +// String salt = Base64.getEncoder().encodeToString(saltBytes); | |
239 | +// String ENC_KEY = Base64.getEncoder().encodeToString(encKeyBytes); | |
240 | +// String iv = Base64.getEncoder().encodeToString(ivBytes); | |
241 | + String salt = generateRandomHex(32); | |
242 | + String ENC_KEY = generateRandomHex(32); | |
243 | + String iv = generateRandomHex(32); | |
244 | + key.put("salt",salt); | |
245 | + key.put("ENC_KEY",ENC_KEY); | |
246 | + key.put("iv",iv); | |
247 | + | |
248 | + target.getSession().setAttribute("key", key); | |
249 | + | |
250 | + //종료 | |
251 | + | |
252 | + | |
253 | + //현재 Client의 IP set | |
254 | + target.getSession().setAttribute("ip", CommonUtil.getClientIp()); | |
255 | +// target.getSession().setAttribute("key",); | |
256 | + | |
257 | + //세션 저장소에 set | |
258 | + sessions.put(target.getSession().getId(), target.getSession()); | |
259 | + } | |
260 | + | |
261 | + /** | |
262 | + * HttpSessionListener Interface로 부터 상속 받은 메소드 | |
263 | + * | |
264 | + * tomcat에서 session이 소멸되었을 때, 발생하는 이벤트 | |
265 | + * @param target : session 이벤트(소멸) 객체 | |
266 | + * | |
267 | + * session 제거 이벤트가 발생하면 Custom session 저장소(sessions)에 해당 session ID 값을 가지고 있는 session 무효화 및 제거 | |
268 | + */ | |
269 | + @Override | |
270 | + public void sessionDestroyed(HttpSessionEvent target) { | |
271 | + //소멸된 세션 Custom session 저장소에서 가지고 오기 | |
272 | + if (sessions.get(target.getSession().getId()) != null) { | |
273 | + //소멸된 세션 무효화 시키기 (가능한지 모르겠지만, 일단 작성해봄) | |
274 | + sessions.get(target.getSession().getId()).invalidate(); | |
275 | + //Custom session 저장소에서 해당 session 삭제 | |
276 | + sessions.remove(target.getSession().getId()); | |
277 | + } else { | |
278 | + return; | |
279 | + } | |
280 | + } | |
281 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/SftpUtil.java
... | ... | @@ -0,0 +1,1384 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
4 | +import com.jcraft.jsch.*; | |
5 | +import com.takensoft.taken_bi_manager.common.connection.db.util.DataTypeUtil; | |
6 | +import com.takensoft.taken_bi_manager.common.file.vo.FileInfo; | |
7 | +import com.takensoft.taken_bi_manager.common.vo.CheckMessage; | |
8 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
9 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode; | |
10 | +import com.takensoft.taken_bi_manager.data.vo.ColumnData; | |
11 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
12 | +import com.takensoft.taken_bi_manager.host.vo.ConnectionVO; | |
13 | +import com.takensoft.taken_bi_manager.host.vo.FilesVO; | |
14 | +import com.takensoft.taken_bi_manager.host.vo.SftpVO; | |
15 | +import com.takensoft.taken_bi_manager.jobs.vo.JobItm; | |
16 | +import org.apache.commons.io.FileUtils; | |
17 | +import org.apache.poi.ss.usermodel.*; | |
18 | +import org.apache.poi.xssf.usermodel.XSSFWorkbook; | |
19 | +import org.springframework.beans.factory.annotation.Autowired; | |
20 | +import org.springframework.http.HttpStatus; | |
21 | + | |
22 | +import java.io.*; | |
23 | +import java.nio.file.Files; | |
24 | +import java.text.SimpleDateFormat; | |
25 | +import java.util.*; | |
26 | +import java.util.stream.Collectors; | |
27 | + | |
28 | +import static com.takensoft.taken_bi_manager.data.util.DataTableConvert.fileToDataset; | |
29 | + | |
30 | +public class SftpUtil { | |
31 | + | |
32 | + private Session session = null; | |
33 | + private Channel channel = null; | |
34 | + private ChannelSftp channelSftp = null; | |
35 | + | |
36 | + | |
37 | + /** | |
38 | + * sftp 연결 | |
39 | + * | |
40 | + * @author 김성훈 | |
41 | + * @since 2024.01.02 | |
42 | + */ | |
43 | + public CheckMessage sftpConnection(ConnectionVO.Host host) { | |
44 | + CheckMessage checkMessage = new CheckMessage(); | |
45 | + | |
46 | + JSch jSch = new JSch(); | |
47 | + | |
48 | + try { | |
49 | + | |
50 | + session = jSch.getSession(host.getHost_id(), host.getHost_ip()); | |
51 | + session.setPassword(host.getHost_pw()); | |
52 | + java.util.Properties config = new java.util.Properties(); | |
53 | + | |
54 | + config.put("StrictHostKeyChecking", "no"); | |
55 | + session.setConfig(config); | |
56 | + session.connect(); | |
57 | + | |
58 | + channel = session.openChannel("sftp"); | |
59 | + channel.connect(); | |
60 | + | |
61 | + channelSftp = (ChannelSftp)channel; | |
62 | + | |
63 | + checkMessage.setMessage(host.getHost_nm() + " 연결에 성공하였습니다."); | |
64 | + checkMessage.setStatus(HttpStatus.OK.value()); | |
65 | + | |
66 | + } catch (JSchException e) { | |
67 | + | |
68 | + e.printStackTrace(); | |
69 | + if("java.net.ConnectException: Connection timed out: connect".equals(e.getMessage())) { | |
70 | + checkMessage.setMessage(host.getHost_nm() + " 연결에 실패하였습니다.(연결 시간 초과)"); | |
71 | + | |
72 | + } else if("Auth fail".equals(e.getMessage())) { | |
73 | + checkMessage.setMessage(host.getHost_nm() + " 연결에 실패하였습니다.(계정 정보 불일치)"); | |
74 | + } | |
75 | + checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
76 | + | |
77 | + } | |
78 | + | |
79 | + return checkMessage; | |
80 | + | |
81 | + } | |
82 | + | |
83 | + /** | |
84 | + * sftp 해제 | |
85 | + * | |
86 | + * @author 김성훈 | |
87 | + * @since 2024.01.02 | |
88 | + */ | |
89 | + public void sftpDisconnection(SftpVO sftpVO) { | |
90 | + if(sftpVO.getSftpUtil().channelSftp != null) { | |
91 | + sftpVO.getSftpUtil().channelSftp.quit(); | |
92 | + } | |
93 | + if(sftpVO.getSftpUtil().channel != null) { | |
94 | + sftpVO.getSftpUtil().channel.disconnect(); | |
95 | + } | |
96 | + if(sftpVO.getSftpUtil().session != null) { | |
97 | + sftpVO.getSftpUtil().session.disconnect(); | |
98 | + } | |
99 | + } | |
100 | + | |
101 | + /** | |
102 | + * fileTree init | |
103 | + * | |
104 | + * @author 김성훈 | |
105 | + * @since 2024.02.02 | |
106 | + */ | |
107 | + public CustomeResultMap fileTree(ConnectionVO.Connection connection) { | |
108 | + | |
109 | + // 결과맵 생성 | |
110 | + CustomeResultMap resultMap = new CustomeResultMap(); | |
111 | + | |
112 | + try { | |
113 | + | |
114 | + // 루트 폴더 설정 | |
115 | + String rootPath = this.rootPath(connection.getPath()); | |
116 | + | |
117 | + // 파일 리스트 및 FileDTO 생성 | |
118 | + List<FilesVO> fileList = new ArrayList<>(); | |
119 | + FilesVO filesVO = new FilesVO(); | |
120 | + | |
121 | + // 루트 폴더 추가 | |
122 | + this.fileListAdd(null, rootPath, filesVO, "folder"); | |
123 | + fileList.add(filesVO); | |
124 | + | |
125 | + // 자식 폴더 추가 | |
126 | + this.scanDir(filesVO.getPath(), filesVO.getChildren(), connection.getType(), connection.getDepth()); | |
127 | + | |
128 | + resultMap.getResultData().put("fileTree", fileList); | |
129 | + | |
130 | + return resultMap; | |
131 | + | |
132 | + } catch (Exception e) { | |
133 | + | |
134 | + e.printStackTrace(); | |
135 | + return null; | |
136 | + | |
137 | + } | |
138 | + } | |
139 | + | |
140 | + /** | |
141 | + * fileList | |
142 | + * | |
143 | + * @author 김성훈 | |
144 | + * @since 2024.02.02 | |
145 | + */ | |
146 | + public CustomeResultMap fileList(ConnectionVO.Connection connection) { | |
147 | + // 결과맵 생성 | |
148 | + CustomeResultMap resultMap = new CustomeResultMap(); | |
149 | + | |
150 | + try { | |
151 | + | |
152 | + // 파일 리스트 및 FileDTO 생성 | |
153 | + List<FilesVO> fileList = this.scanDir(connection.getPath(), new ArrayList<FilesVO>(), connection.getType(), connection.getDepth()); | |
154 | + | |
155 | + // 상위 폴더가기 구현 | |
156 | + if( "all".equals(connection.getType()) || "file".equals(connection.getType())) { | |
157 | + connection.getPath(); | |
158 | + if(!connection.getPath().equals("/home")) { | |
159 | + FilesVO temp = new FilesVO(); | |
160 | + String parentPath = this.parentPath(connection.getPath()); | |
161 | + this.fileListAdd(null, parentPath, temp, "folder"); | |
162 | + temp.setText("상위폴더로 이동"); | |
163 | + temp.setExtension(""); | |
164 | + fileList.add(0,temp); | |
165 | + | |
166 | + resultMap.getResultData().put("totalRow", fileList.size() - 1); | |
167 | + } else { | |
168 | + resultMap.getResultData().put("totalRow", fileList.size()); | |
169 | + } | |
170 | + } | |
171 | + | |
172 | + resultMap.getResultData().put("fileList", fileList); | |
173 | + | |
174 | + return resultMap; | |
175 | + | |
176 | + } catch (Exception e) { | |
177 | + | |
178 | + e.printStackTrace(); | |
179 | + return null; | |
180 | + | |
181 | + } | |
182 | + | |
183 | + } | |
184 | + | |
185 | + /** | |
186 | + * FILE -> FileDTO로 변환 | |
187 | + * | |
188 | + * @author 김성훈 | |
189 | + * @since 2024.01.03 | |
190 | + */ | |
191 | + public void fileListAdd(ChannelSftp.LsEntry lsEntry, String path, FilesVO filesVO, String fileType) throws Exception { | |
192 | + // 루트 폴더가 아닐때 | |
193 | + if(lsEntry != null) { | |
194 | + | |
195 | + SftpATTRS attrs = lsEntry.getAttrs(); | |
196 | + filesVO.setId(path); | |
197 | + filesVO.setText(lsEntry.getFilename()); | |
198 | + filesVO.setPath(path); | |
199 | + | |
200 | + // 시간변환 | |
201 | + SimpleDateFormat inFormat = new SimpleDateFormat ("EEE MMM d HH:mm:ss Z yyyy", Locale.ENGLISH); | |
202 | + Date date = inFormat.parse(lsEntry.getAttrs().getMtimeString()); | |
203 | + SimpleDateFormat outFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |
204 | + String formatDate = outFormat.format(date); | |
205 | + | |
206 | + filesVO.setLastUpdate(formatDate); | |
207 | + // 폴더인지 파일인지 확인 | |
208 | + if("folder".equals(fileType)) { | |
209 | + filesVO.setSize(0); | |
210 | + filesVO.setFolder(true); | |
211 | + filesVO.setExtension("폴더"); | |
212 | + filesVO.setSort(0); | |
213 | + } else { | |
214 | + filesVO.setSize(attrs.getSize()); | |
215 | + filesVO.setFolder(false); | |
216 | + filesVO.setExtension(this.splitLastString(lsEntry.getFilename(), '.')); | |
217 | + filesVO.setSort(1); | |
218 | + } | |
219 | + | |
220 | + // 루트 폴더 일때 | |
221 | + } else { | |
222 | + filesVO.setId(path); | |
223 | + filesVO.setPath(path); | |
224 | + filesVO.setFolder(true); | |
225 | + filesVO.setSize(0); | |
226 | + filesVO.setExtension("폴더"); | |
227 | + filesVO.setSort(0); | |
228 | + if(path != "/") { | |
229 | + filesVO.setText(this.splitLastString(path, '/')); | |
230 | + } else { | |
231 | + filesVO.setText("/"); | |
232 | + } | |
233 | + | |
234 | + } | |
235 | + } | |
236 | + | |
237 | + /** | |
238 | + * 파일 경로를 이용하여 경로에 존재하는 폴더 및 파일 찾기 | |
239 | + * | |
240 | + * @author 김성훈 | |
241 | + * @since 2024.01.03 | |
242 | + */ | |
243 | + public List<FilesVO> scanDir(String path, List<FilesVO> children, String type, int depth) { | |
244 | + | |
245 | + try { | |
246 | + | |
247 | + List<ChannelSftp.LsEntry> files = null; | |
248 | + | |
249 | + // 폴더 리스트 | |
250 | + files = channelSftp.ls(path); | |
251 | + | |
252 | + //파일 리스트 정렬(알파벳 오름차순) | |
253 | + files = files.stream().sorted(Comparator.comparing(ChannelSftp.LsEntry::getFilename, String.CASE_INSENSITIVE_ORDER)).collect(Collectors.toList()); | |
254 | + | |
255 | + // 자식 폴더가 있을때 | |
256 | + if (files != null || !files.isEmpty()) { | |
257 | + // 파일리스트에 있는 파일한개 가져오기 | |
258 | + for (ChannelSftp.LsEntry lsEntry : files) { | |
259 | + | |
260 | + // 파일명이 . and ..이 아닐때 | |
261 | + if (!".".equals(lsEntry.getFilename()) && !"..".equals(lsEntry.getFilename())) { | |
262 | + SftpATTRS attrs = lsEntry.getAttrs(); | |
263 | + | |
264 | + String childrenPath; | |
265 | + // 파일 패스 만들기 | |
266 | + if (path != "/") { | |
267 | + childrenPath = path + "/" + lsEntry.getFilename(); | |
268 | + } else { | |
269 | + childrenPath = path + lsEntry.getFilename(); | |
270 | + } | |
271 | + | |
272 | + // 폴더이거나 링크폴더일 경우 | |
273 | + if (attrs.isDir() || attrs.isLink()) { | |
274 | + if ("all".equals(type) || "folder".equals(type)) { | |
275 | + FilesVO temp = new FilesVO(); | |
276 | + | |
277 | + // lsEntry -> 파일DTO로 변환 | |
278 | + this.fileListAdd(lsEntry, childrenPath, temp, "folder"); | |
279 | + temp.setParent(this.parentPath(childrenPath)); | |
280 | + // 부모 폴더 자식에 추가 | |
281 | + children.add(temp); | |
282 | + //폴더 깊이가 0이면 다음 깊이(자식) 한번 더 검색 | |
283 | + if (depth < 1) { | |
284 | + scanDir(childrenPath, temp.getChildren(), type, depth + 1); | |
285 | + } | |
286 | + } | |
287 | + } else { | |
288 | + // 파일검색 일때 | |
289 | + if ("all".equals(type) || "file".equals(type)) { | |
290 | + FilesVO temp = new FilesVO(); | |
291 | + // lsEntry -> 파일DTO로 변환 | |
292 | + this.fileListAdd(lsEntry, childrenPath, temp, "file"); | |
293 | + temp.setParent(this.parentPath(childrenPath)); | |
294 | + // 부모 폴더 자식에 추가 | |
295 | + children.add(temp); | |
296 | + } | |
297 | + } | |
298 | + } | |
299 | + } | |
300 | + } | |
301 | + //파일 리스트 정렬(폴더가 위로 -> 파일이름) | |
302 | + children = children.stream().sorted(Comparator.comparingInt(FilesVO::getSort)).collect(Collectors.toList()); | |
303 | + return children; | |
304 | + | |
305 | + } catch (Exception e) { | |
306 | + | |
307 | + e.printStackTrace(); | |
308 | + return null; | |
309 | + | |
310 | + } | |
311 | + } | |
312 | + | |
313 | + /** | |
314 | + * 폴더 생성 | |
315 | + * | |
316 | + * @author 김성훈 | |
317 | + * @since 2024.02.08 | |
318 | + */ | |
319 | + public CheckMessage mkdir(ConnectionVO.Mkdir mkdir) { | |
320 | + CheckMessage checkMessage = new CheckMessage(); | |
321 | + String dirPath = mkdir.getPath() + "/" + mkdir.getFolderName(); | |
322 | + try { | |
323 | + if(!this.exists(dirPath)) { | |
324 | +// channelSftp.cd(mkdir.getPath()); | |
325 | + channelSftp.mkdir(dirPath); | |
326 | + checkMessage.setMessage(mkdir.getFolderName() + " 폴더를 추가 하였습니다."); | |
327 | + } else { | |
328 | + checkMessage.setMessage(mkdir.getFolderName() + "은(는) 이미 존재하는 폴더명입니다."); | |
329 | + } | |
330 | + checkMessage.setStatus(HttpStatus.OK.value()); | |
331 | + } catch (Exception e){ | |
332 | + e.printStackTrace(); | |
333 | + checkMessage.setMessage("오류발생. 잠시후 다시 시도해주세요."); | |
334 | + checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
335 | + } | |
336 | + | |
337 | + return checkMessage; | |
338 | + } | |
339 | + | |
340 | + /** | |
341 | + * 파일 업로드 | |
342 | + * | |
343 | + * @author 김성훈 | |
344 | + * @since 2024.02.13 | |
345 | + */ | |
346 | + public CheckMessage fileUpload(ConnectionVO.FileUpload fileUpload) { | |
347 | + CheckMessage checkMessage = new CheckMessage(); | |
348 | + | |
349 | + String filePath = fileUpload.getPath() + "/" + fileUpload.getUploadFile().getOriginalFilename(); | |
350 | + | |
351 | + try (InputStream inputStream = fileUpload.getUploadFile().getInputStream()){ | |
352 | + | |
353 | + if(!fileUpload.isConfirm()) { | |
354 | + if(!this.exists(filePath)) { | |
355 | + channelSftp.put(inputStream, filePath, new Monitor()); | |
356 | + checkMessage.setMessage(fileUpload.getUploadFile().getOriginalFilename() + " 파일을 업로드 하였습니다."); | |
357 | + checkMessage.setStatus(HttpStatus.OK.value()); | |
358 | + } else { | |
359 | + checkMessage.setMessage(fileUpload.getUploadFile().getOriginalFilename() + "이(가) 이미 존재합니다. 덮어쓰시겠습니까?"); | |
360 | + checkMessage.setStatus(HttpStatus.CONTINUE.value()); | |
361 | + } | |
362 | + } else { | |
363 | + channelSftp.put(inputStream, filePath, new Monitor()); | |
364 | + | |
365 | + checkMessage.setMessage("덮어쓰기를 완료 하였습니다."); | |
366 | + checkMessage.setStatus(HttpStatus.OK.value()); | |
367 | + } | |
368 | + | |
369 | + } catch (Exception e) { | |
370 | + | |
371 | + e.printStackTrace(); | |
372 | + checkMessage.setMessage("오류발생. 잠시후 다시 시도해주세요."); | |
373 | + checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
374 | + | |
375 | + } | |
376 | + | |
377 | + return checkMessage; | |
378 | + } | |
379 | + | |
380 | + /** | |
381 | + * 파일 다운로드 | |
382 | + * | |
383 | + * @author 김성훈 | |
384 | + * @since 2024.02.14 | |
385 | + */ | |
386 | + public CheckMessage fileDownload(ConnectionVO.FileDownload fileDownload, String host_nm) { | |
387 | + CheckMessage checkMessage = new CheckMessage(); | |
388 | + String filePath = fileDownload.getPath() + "/" + fileDownload.getFileName(); | |
389 | + | |
390 | + FileOutputStream out = null; | |
391 | + try { | |
392 | + | |
393 | + //로컬에 저장 폴더 있는지 확인 | |
394 | + String absolutePath = SystemCode.FileUploadPath.SFTP_ABSOLUTE_PATH.getOSFileUploadPath() + "/" + host_nm; | |
395 | + File dir = new File(absolutePath); | |
396 | + | |
397 | + if (dir.exists() == false) { | |
398 | + dir.mkdirs(); | |
399 | + } | |
400 | + | |
401 | + if(this.exists(filePath)) { | |
402 | + channelSftp.cd(fileDownload.getPath()); | |
403 | + | |
404 | + out = new FileOutputStream(new File(absolutePath + "/" + fileDownload.getFileName())); | |
405 | + | |
406 | + channelSftp.get(fileDownload.getFileName(), out, new Monitor()); | |
407 | + | |
408 | + checkMessage.setMessage("파일 다운로드를 완료 하였습니다."); | |
409 | + } else { | |
410 | + checkMessage.setMessage("존재하지 않는 파일입니다."); | |
411 | + } | |
412 | + | |
413 | + checkMessage.setStatus(HttpStatus.OK.value()); | |
414 | + | |
415 | + return checkMessage; | |
416 | + | |
417 | + } catch (Exception e) { | |
418 | + | |
419 | + e.printStackTrace(); | |
420 | + checkMessage.setMessage("오류발생. 잠시후 다시 시도해주세요."); | |
421 | + checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
422 | + return checkMessage; | |
423 | + | |
424 | + } finally { | |
425 | + | |
426 | + if(out != null) { | |
427 | + try { | |
428 | + out.flush(); | |
429 | + out.close(); | |
430 | + } catch (IOException e) { | |
431 | + e.printStackTrace(); | |
432 | + | |
433 | + checkMessage.setMessage("오류발생. 잠시후 다시 시도해주세요."); | |
434 | + checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
435 | + return checkMessage; | |
436 | + } | |
437 | + } | |
438 | + } | |
439 | + } | |
440 | + | |
441 | + /** | |
442 | + * 폴더, 파일 이름 변경 | |
443 | + * | |
444 | + * @author 김성훈 | |
445 | + * @since 2024.02.15 | |
446 | + */ | |
447 | + public CheckMessage fileReName(ConnectionVO.Rename rename) { | |
448 | + CheckMessage checkMessage = new CheckMessage(); | |
449 | + | |
450 | + try { | |
451 | + | |
452 | + if(this.exists(rename.getCurrentPath())) { | |
453 | + channelSftp.rename(rename.getCurrentPath(), rename.getChangePath()); | |
454 | + checkMessage.setMessage("이름 변경을 완료 하였습니다."); | |
455 | + } else { | |
456 | + checkMessage.setMessage("존재하지 않는 파일 입니다."); | |
457 | + } | |
458 | + checkMessage.setStatus(HttpStatus.OK.value()); | |
459 | + | |
460 | + } catch (Exception e){ | |
461 | + | |
462 | + e.printStackTrace(); | |
463 | + checkMessage.setMessage("오류발생. 잠시후 다시 시도해주세요."); | |
464 | + checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
465 | + | |
466 | + } | |
467 | + | |
468 | + return checkMessage; | |
469 | + } | |
470 | + | |
471 | + /** | |
472 | + * 폴더, 파일 삭제 | |
473 | + * | |
474 | + * @author 김성훈 | |
475 | + * @since 2024.02.15 | |
476 | + */ | |
477 | + public CheckMessage fileRemove(List<ConnectionVO.Remove> removeList) { | |
478 | + CheckMessage checkMessage = new CheckMessage(); | |
479 | + | |
480 | + try { | |
481 | + | |
482 | + for (ConnectionVO.Remove remove : removeList) { | |
483 | + if(this.exists(remove.getPath())) { | |
484 | + if(remove.isFolder()) { | |
485 | +// channelSftp.cd(remove.getPath()); | |
486 | + List<ChannelSftp.LsEntry> ls = channelSftp.ls(remove.getPath()); | |
487 | + | |
488 | + if(ls.size() != 2) { | |
489 | + this.rmdir(ls, remove.getPath()); | |
490 | + } | |
491 | + channelSftp.rmdir(remove.getPath()); | |
492 | + | |
493 | + } else { | |
494 | + channelSftp.rm(remove.getPath()); | |
495 | + } | |
496 | + checkMessage.setMessage("삭제를 완료 하였습니다."); | |
497 | + } else { | |
498 | + checkMessage.setMessage("이미 삭제된 파일 입니다."); | |
499 | + | |
500 | + } | |
501 | + checkMessage.setStatus(HttpStatus.OK.value()); | |
502 | + } | |
503 | + | |
504 | + } catch (Exception e){ | |
505 | + | |
506 | + e.printStackTrace(); | |
507 | + checkMessage.setMessage("오류발생. 잠시후 다시 시도해주세요."); | |
508 | + checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
509 | + | |
510 | + } | |
511 | + | |
512 | + return checkMessage; | |
513 | + } | |
514 | + | |
515 | + /** | |
516 | + * @author 김성훈 | |
517 | + * @since 2024.02.08 | |
518 | + * | |
519 | + * 폴더 삭제 시 하위 폴더 안 파일 부터 삭제 | |
520 | + */ | |
521 | + public void rmdir(List<ChannelSftp.LsEntry> ls, String path) throws SftpException { | |
522 | + | |
523 | + for (ChannelSftp.LsEntry lsEntry : ls) { | |
524 | + if (!".".equals(lsEntry.getFilename()) && !"..".equals(lsEntry.getFilename())) { | |
525 | + String lsPath = path + "/" + lsEntry.getFilename(); | |
526 | + if(this.exists(lsPath)) { | |
527 | + SftpATTRS attrs = lsEntry.getAttrs(); | |
528 | + if (attrs.isDir() || attrs.isLink()) { | |
529 | +// channelSftp.cd(lsPath); | |
530 | + List<ChannelSftp.LsEntry> childrenLs = channelSftp.ls(lsPath); | |
531 | + if(ls.size() != 2) { | |
532 | + this.rmdir(childrenLs, lsPath); | |
533 | + } | |
534 | + channelSftp.rmdir(lsPath); | |
535 | + } else { | |
536 | + channelSftp.rm(lsPath); | |
537 | + } | |
538 | + } | |
539 | + } | |
540 | + } | |
541 | + } | |
542 | + | |
543 | + /** | |
544 | + * 파일 이동 | |
545 | + * | |
546 | + * @author 김성훈 | |
547 | + * @since 2024.02.16 | |
548 | + */ | |
549 | + public CustomeResultMap fileMove(ConnectionVO.MoveList moveList) { | |
550 | + CustomeResultMap customeResultMap = new CustomeResultMap(); | |
551 | + //폴더 리스트 | |
552 | + List<ConnectionVO.Move> fileList = moveList.getFileList(); | |
553 | + List<ConnectionVO.Remove> removeFolderList = moveList.getRemoveFolder(); | |
554 | + | |
555 | + try { | |
556 | + if("cancel".equals(moveList.getType())) { | |
557 | + fileList.remove(0); | |
558 | + } | |
559 | + | |
560 | + for (int i = 0; i < fileList.size(); i++) { | |
561 | + ConnectionVO.Move move = fileList.get(i); | |
562 | + | |
563 | + if(!moveList.isCheck()) { | |
564 | + if (!move.isFolder()) { | |
565 | + if (!this.exists(move.getMovePath() + "/" + move.getFileName())) { | |
566 | + channelSftp.rename(move.getPath(), move.getMovePath() + "/" + move.getFileName()); | |
567 | + } else { | |
568 | + if("move".equals(moveList.getType())) { | |
569 | + channelSftp.rename(move.getPath(), move.getMovePath() + "/" + move.getFileName()); | |
570 | + moveList.setType("confirm"); | |
571 | + } else { | |
572 | + customeResultMap.getCheckMessage().setMessage(move.getFileName() + "이(가) 이미 존재합니다. 동작을 선택하십시오."); | |
573 | + customeResultMap.getCheckMessage().setStatus(HttpStatus.CONTINUE.value()); | |
574 | + customeResultMap.getResultData().put("removeFolderList", removeFolderList); | |
575 | + customeResultMap.getResultData().put("fileList", fileList.subList(i, fileList.size())); | |
576 | + return customeResultMap; | |
577 | + } | |
578 | + } | |
579 | + } else { | |
580 | + | |
581 | + if(!this.exists(move.getMovePath() + "/" + move.getFileName())) { | |
582 | + channelSftp.mkdir(move.getMovePath() + "/" + move.getFileName()); | |
583 | + } | |
584 | + | |
585 | + List<ChannelSftp.LsEntry> files = null; | |
586 | + List<ConnectionVO.Move> filesSearchList = new ArrayList<>(); | |
587 | + | |
588 | + // 폴더 리스트 | |
589 | + files = channelSftp.ls(move.getPath()); | |
590 | + | |
591 | + // 자식이 있을때 | |
592 | + if(files != null && !files.isEmpty()) { | |
593 | + // 파일리스트에 있는 파일한개 가져오기 | |
594 | + for (ChannelSftp.LsEntry lsEntry : files) { | |
595 | + // 파일명이 . and ..이 아닐때 | |
596 | + if (!".".equals(lsEntry.getFilename()) && !"..".equals(lsEntry.getFilename())) { | |
597 | + SftpATTRS attrs = lsEntry.getAttrs(); | |
598 | + | |
599 | + ConnectionVO.Move moveFile = new ConnectionVO.Move(); | |
600 | + | |
601 | + moveFile.setFileName(lsEntry.getFilename()); | |
602 | + moveFile.setMovePath(move.getMovePath() + '/' + move.getFileName()); | |
603 | + moveFile.setPath(move.getPath() + '/' + lsEntry.getFilename()); | |
604 | + moveFile.setFolder(false); | |
605 | + | |
606 | + if (attrs.isDir() || attrs.isLink()) { | |
607 | + moveFile.setFolder(true); | |
608 | + } | |
609 | + filesSearchList.add(moveFile); | |
610 | + } | |
611 | + } | |
612 | + } | |
613 | + fileList.addAll(filesSearchList); | |
614 | + | |
615 | + ConnectionVO.Remove remove = new ConnectionVO.Remove(); | |
616 | + remove.setPath(move.getPath()); | |
617 | + remove.setFolder(true); | |
618 | + removeFolderList.add(remove); | |
619 | + } | |
620 | + } else { | |
621 | + if("move".equals(moveList.getType())) { | |
622 | + channelSftp.rename(move.getPath(), move.getMovePath() + "/" + move.getFileName()); | |
623 | + } else { | |
624 | + if (!this.exists(move.getMovePath() + "/" + move.getFileName())) { | |
625 | + channelSftp.rename(move.getPath(), move.getMovePath() + "/" + move.getFileName()); | |
626 | + } | |
627 | + } | |
628 | + | |
629 | + } | |
630 | + } | |
631 | + | |
632 | + customeResultMap.getResultData().put("removeFolderList", removeFolderList); | |
633 | + customeResultMap.getCheckMessage().setStatus(HttpStatus.OK.value()); | |
634 | + customeResultMap.getCheckMessage().setMessage("파일이동을 완료 하였습니다."); | |
635 | + | |
636 | + } catch (Exception e){ | |
637 | + e.printStackTrace(); | |
638 | + customeResultMap.getCheckMessage().setMessage("오류발생. 잠시후 다시 시도해주세요."); | |
639 | + customeResultMap.getCheckMessage().setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
640 | + } | |
641 | + | |
642 | + return customeResultMap; | |
643 | + } | |
644 | + | |
645 | + /** | |
646 | + * 폴더, 파일 이동 후 비어있는 폴더 지우기 | |
647 | + * | |
648 | + * @author 김성훈 | |
649 | + * @since 2024.03.11 | |
650 | + */ | |
651 | + public CheckMessage removeFolder(List<ConnectionVO.Remove> folderList) { | |
652 | + CheckMessage checkMessage = new CheckMessage(); | |
653 | + | |
654 | + try { | |
655 | + for (int i = folderList.size(); i > 0; i--) { | |
656 | + ConnectionVO.Remove remove = folderList.get(i-1); | |
657 | + | |
658 | + if(this.exists(remove.getPath())) { | |
659 | + Vector ls = channelSftp.ls(remove.getPath()); | |
660 | + | |
661 | + if(ls.size() == 2) { | |
662 | + channelSftp.rmdir(remove.getPath()); | |
663 | + } | |
664 | + } | |
665 | + } | |
666 | + | |
667 | + } catch(Exception e) { | |
668 | + e.printStackTrace(); | |
669 | + checkMessage.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
670 | + checkMessage.setMessage("이동 완료 후 서버 오류로 인해 원본 폴더가 삭제되지 않았습니다. 삭제를 원하시면 원본 폴더를 삭제해주세요."); | |
671 | + } | |
672 | + return checkMessage; | |
673 | + } | |
674 | + | |
675 | + /** | |
676 | + * 파일 복사 | |
677 | + * | |
678 | + * @author 김성훈 | |
679 | + * @since 2024.03.07 | |
680 | + */ | |
681 | + public CustomeResultMap fileCopy(ConnectionVO.CopyList copyList) { | |
682 | + CustomeResultMap customeResultMap = new CustomeResultMap(); | |
683 | + //폴더 리스트 | |
684 | + List<ConnectionVO.Move> fileList = copyList.getFileList(); | |
685 | + | |
686 | + try { | |
687 | + | |
688 | + if("cancel".equals(copyList.getType())) { | |
689 | + fileList.remove(0); | |
690 | + } | |
691 | + | |
692 | + for (int i = 0; i < fileList.size(); i++) { | |
693 | + ConnectionVO.Move move = fileList.get(i); | |
694 | + | |
695 | + if(!copyList.isCheck()) { | |
696 | + if (!move.isFolder()) { // 폴더가 아닐 때 | |
697 | + if (!this.exists(move.getMovePath() + "/" + move.getFileName())) { // 이동할 폴더에 동일한 이름의 파일이 없을 때 | |
698 | +// this.inputCopy(move.getPath(), move.getMovePath() + "/" + move.getFileName()); // 파일 복사 | |
699 | + this.inputMoveCopy(move); // 파일 이동 복사 | |
700 | + } else { // 이동할 폴더에 동일한 이름의 파일이 있을 경우 | |
701 | + if("move".equals(copyList.getType())) { | |
702 | +// this.inputCopy(move.getPath(), move.getMovePath() + "/" + move.getFileName()); | |
703 | + this.inputMoveCopy(move); // 파일 이동 복사 | |
704 | + copyList.setType("confirm"); | |
705 | + } else { | |
706 | + customeResultMap.getCheckMessage().setMessage(move.getFileName() + "이(가) 이미 존재합니다. 동작을 선택하십시오."); | |
707 | + customeResultMap.getCheckMessage().setStatus(HttpStatus.CONTINUE.value()); | |
708 | + customeResultMap.getResultData().put("fileList", fileList.subList(i, fileList.size())); | |
709 | + return customeResultMap; | |
710 | + } | |
711 | + } | |
712 | + } else { // 폴더일 때 | |
713 | + | |
714 | + if(!this.exists(move.getMovePath() + "/" + move.getFileName())) { // 이동할 폴더에 동일한 이름의 폴더가 없을 때 | |
715 | + channelSftp.mkdir(move.getMovePath() + "/" + move.getFileName()); // 폴더 생성 | |
716 | + } | |
717 | + | |
718 | + List<ChannelSftp.LsEntry> files = null; | |
719 | + List<ConnectionVO.Move> filesSearchList = new ArrayList<>(); | |
720 | + | |
721 | + // 폴더 리스트 | |
722 | + files = channelSftp.ls(move.getPath()); | |
723 | + | |
724 | + // 자식이 있을때 | |
725 | + if(files != null && !files.isEmpty()) { | |
726 | + // 파일리스트에 있는 파일한개 가져오기 | |
727 | + for (ChannelSftp.LsEntry lsEntry : files) { | |
728 | + // 파일명이 . and ..이 아닐때 | |
729 | + if (!".".equals(lsEntry.getFilename()) && !"..".equals(lsEntry.getFilename())) { | |
730 | + SftpATTRS attrs = lsEntry.getAttrs(); | |
731 | + | |
732 | + ConnectionVO.Move moveFile = new ConnectionVO.Move(); | |
733 | + | |
734 | + moveFile.setFileName(lsEntry.getFilename()); | |
735 | + moveFile.setMovePath(move.getMovePath() + '/' + move.getFileName()); | |
736 | + moveFile.setPath(move.getPath() + '/' + lsEntry.getFilename()); | |
737 | + moveFile.setFolder(false); | |
738 | + | |
739 | + if (attrs.isDir() || attrs.isLink()) { | |
740 | + moveFile.setFolder(true); | |
741 | + } | |
742 | + filesSearchList.add(moveFile); | |
743 | + } | |
744 | + } | |
745 | + } | |
746 | + fileList.addAll(filesSearchList); | |
747 | + | |
748 | + } | |
749 | + } else { | |
750 | + if("move".equals(copyList.getType())) { | |
751 | +// this.inputCopy(move.getPath(), move.getMovePath() + "/" + move.getFileName()); | |
752 | + this.inputMoveCopy(move); // 파일 이동 복사 | |
753 | + } else { | |
754 | + if (!this.exists(move.getMovePath() + "/" + move.getFileName())) { | |
755 | +// this.inputCopy(move.getPath(), move.getMovePath() + "/" + move.getFileName()); | |
756 | + this.inputMoveCopy(move); // 파일 이동 복사 | |
757 | + } | |
758 | + } | |
759 | + } | |
760 | + } | |
761 | + | |
762 | + customeResultMap.getCheckMessage().setStatus(HttpStatus.OK.value()); | |
763 | + customeResultMap.getCheckMessage().setMessage("파일복사를 완료 하였습니다."); | |
764 | + | |
765 | + } catch (Exception e){ | |
766 | + e.printStackTrace(); | |
767 | + customeResultMap.getCheckMessage().setMessage("오류발생. 잠시후 다시 시도해주세요."); | |
768 | + customeResultMap.getCheckMessage().setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
769 | + } | |
770 | + | |
771 | + return customeResultMap; | |
772 | + } | |
773 | + | |
774 | + /** | |
775 | + * @author 김성훈 | |
776 | + * @since 2024.03.13 | |
777 | + * | |
778 | + * 파일 복사 시작 | |
779 | + */ | |
780 | + public void inputCopy(String path, String movePath) throws Exception { | |
781 | + | |
782 | + Channel copyChannel = session.openChannel("sftp"); | |
783 | + copyChannel.connect(); | |
784 | + ChannelSftp copyChannelSftp = (ChannelSftp)copyChannel; | |
785 | + | |
786 | + try(InputStream inputStream = channelSftp.get(path)) { | |
787 | + copyChannelSftp.put(inputStream, movePath, new Monitor()); | |
788 | + } catch(Exception e) { | |
789 | + e.printStackTrace(); | |
790 | + throw new IOException(); | |
791 | + } | |
792 | + } | |
793 | + | |
794 | + /** | |
795 | + * @author 김성훈 | |
796 | + * @since 2024.03.13 | |
797 | + * | |
798 | + * 파일 검색 | |
799 | + */ | |
800 | + public CustomeResultMap fileSearch(String path, List<FilesVO> fileList, String searchText) { | |
801 | + CustomeResultMap customeResultMap = new CustomeResultMap(); | |
802 | + | |
803 | + try { | |
804 | + List<ChannelSftp.LsEntry> files = null; | |
805 | + | |
806 | + // 폴더 리스트 | |
807 | + files = channelSftp.ls(path); | |
808 | + | |
809 | + // 자식 폴더가 있을때 | |
810 | + if (files != null || !files.isEmpty()) { | |
811 | + | |
812 | + // 파일리스트에 있는 파일한개 가져오기 | |
813 | + for (ChannelSftp.LsEntry lsEntry : files) { | |
814 | + // 파일명이 . and ..이 아닐때 | |
815 | + if (!".".equals(lsEntry.getFilename()) && !"..".equals(lsEntry.getFilename())) { | |
816 | + SftpATTRS attrs = lsEntry.getAttrs(); | |
817 | + | |
818 | + String childrenPath; | |
819 | + // 파일 패스 만들기 | |
820 | + if (path != "/") { | |
821 | + childrenPath = path + "/" + lsEntry.getFilename(); | |
822 | + } else { | |
823 | + childrenPath = path + lsEntry.getFilename(); | |
824 | + } | |
825 | + | |
826 | + // 폴더이거나 링크폴더일 경우 | |
827 | + if (attrs.isDir() || attrs.isLink()) { | |
828 | + this.fileSearch(childrenPath, fileList, searchText); | |
829 | + } else { | |
830 | + if(lsEntry.getFilename().contains(searchText)) { | |
831 | + FilesVO temp = new FilesVO(); | |
832 | + // lsEntry -> 파일DTO로 변환 | |
833 | + this.fileListAdd(lsEntry, childrenPath, temp, "file"); | |
834 | + fileList.add(temp); | |
835 | + } | |
836 | + } | |
837 | + } | |
838 | + } | |
839 | + } | |
840 | + | |
841 | + customeResultMap.getResultData().put("fileList", fileList); | |
842 | + customeResultMap.getCheckMessage().setStatus(HttpStatus.OK.value()); | |
843 | + customeResultMap.getCheckMessage().setMessage("파일 검색을 완료 하였습니다."); | |
844 | + } catch(Exception e) { | |
845 | + e.printStackTrace(); | |
846 | + customeResultMap.getCheckMessage().setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
847 | + customeResultMap.getCheckMessage().setMessage("오류발생. 잠시후 다시 시도해주세요."); | |
848 | + | |
849 | + } | |
850 | + return customeResultMap; | |
851 | + } | |
852 | + | |
853 | + /** | |
854 | + * @author 김성훈 | |
855 | + * @since 2024.03.13 | |
856 | + * | |
857 | + * 파일 -> DataTable 변환 | |
858 | + */ | |
859 | + public CustomeResultMap fileRead(FileInfo fileInfo) { | |
860 | + CustomeResultMap customeResultMap = new CustomeResultMap(); | |
861 | + SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |
862 | + | |
863 | + int limit = Integer.MAX_VALUE; | |
864 | + | |
865 | + if(fileInfo.isViewMode() == true) { | |
866 | + limit = 100; | |
867 | + } | |
868 | + | |
869 | + List<FileInfo> files = new ArrayList<>(); | |
870 | + List<DataTable> dataTables = new ArrayList<>(); | |
871 | + | |
872 | + FileInfo backFileInfo = new FileInfo(fileInfo); | |
873 | + | |
874 | + //임시 파일 초기화 | |
875 | + List<File> tempFiles = new ArrayList<>(); | |
876 | + //임시 파일 저장 경로 | |
877 | + String tempPath = SystemCode.FileUploadPath.TEMP_ABSOLUTE_PATH.getOSFileUploadPath(); | |
878 | + | |
879 | + //임시파일 저장 폴더 없으면 생성 | |
880 | + File tempDir = new File(tempPath); | |
881 | + if (tempDir.exists() == false) { | |
882 | + tempDir.mkdirs(); | |
883 | + } | |
884 | + | |
885 | + // 특정 파일 읽기 | |
886 | + if("file".equals(fileInfo.getType())) { | |
887 | + | |
888 | + try(InputStream inputStream = channelSftp.get(backFileInfo.getPath())) { | |
889 | + // 임시파일 생성 | |
890 | + File tempFile = File.createTempFile(String.valueOf(inputStream.hashCode()), "." + backFileInfo.getExtension(), tempDir); | |
891 | + | |
892 | + // 임시파일 쓰기 | |
893 | + FileUtils.copyInputStreamToFile(inputStream, tempFile); | |
894 | + | |
895 | + //FileInfo를 임시파일 정보로 변경 | |
896 | + backFileInfo.fileToFileInfo(tempFile); | |
897 | + | |
898 | + //임시파일 리스트 add | |
899 | + tempFiles.add(tempFile); | |
900 | + //파일읽기 리스트 add | |
901 | + files.add(backFileInfo); | |
902 | + | |
903 | + } catch(Exception e) { | |
904 | + e.printStackTrace(); | |
905 | + } | |
906 | + // 폴더에 있는 파일 목록 읽기 | |
907 | + } else { | |
908 | + | |
909 | + try { | |
910 | + // 폴더 리스트 | |
911 | + List<ChannelSftp.LsEntry> allFiles = channelSftp.ls(fileInfo.getPath()); | |
912 | + | |
913 | + if (allFiles != null || !allFiles.isEmpty()) { | |
914 | + List<ChannelSftp.LsEntry> lsFiles = new ArrayList<>(); | |
915 | + for (ChannelSftp.LsEntry lsEntry : allFiles) { | |
916 | + if(!".".equals(lsEntry.getFilename()) && !"..".equals(lsEntry.getFilename()) && !lsEntry.getAttrs().isDir() && !lsEntry.getAttrs().isLink()) { | |
917 | + lsFiles.add(lsEntry); | |
918 | + } | |
919 | + } | |
920 | + | |
921 | + //파일 리스트 정렬(폴더가 위로 -> 파일이름) | |
922 | + lsFiles = lsFiles.stream().sorted(Comparator.comparingInt(lsEntry -> lsEntry.getAttrs().getMTime())).collect(Collectors.toList()); | |
923 | + | |
924 | + if(fileInfo.isLastData()) { | |
925 | + ChannelSftp.LsEntry lsEntry = lsFiles.get(lsFiles.size() - 1); | |
926 | + try(InputStream inputStream = channelSftp.get(fileInfo.getPath() + "/" + lsEntry.getFilename())) { | |
927 | + // 임시파일 생성 | |
928 | + File tempFile = File.createTempFile(String.valueOf(inputStream.hashCode()), "." + this.splitLastString(lsEntry.getFilename(), '.'), tempDir); | |
929 | + | |
930 | + // 임시파일 쓰기 | |
931 | + FileUtils.copyInputStreamToFile(inputStream, tempFile); | |
932 | + | |
933 | + //FileInfo를 임시파일 정보로 변경 | |
934 | + fileInfo.fileToFileInfo(tempFile); | |
935 | + | |
936 | + //임시파일 리스트 add | |
937 | + tempFiles.add(tempFile); | |
938 | + //파일읽기 리스트 add | |
939 | + files.add(fileInfo); | |
940 | + | |
941 | + } catch(Exception e) { | |
942 | + e.printStackTrace(); | |
943 | + } | |
944 | + } | |
945 | + | |
946 | + if(fileInfo.isDatasetAfter()) { | |
947 | + List<ChannelSftp.LsEntry> datasetAfterFileList = new ArrayList<>(); | |
948 | + Date datasetDate = null; | |
949 | +// 기준 데이터셋 확인 | |
950 | +// if(!StringUtil.isEmpty(fileInfo.getDatasetId())) { | |
951 | +// Dataset dataset = datasetDAO.selectDatasetByPostId(fileInfo.getDatasetId()); | |
952 | +// if(StringUtil.isEmpty(dataset.getUpdtDt().toString())) { | |
953 | +// datasetDate = new Date(sf.parse(dataset.getCreatDt().toString()).getTime()); | |
954 | +// }else { | |
955 | +// datasetDate = new Date(sf.parse(dataset.getUpdtDt().toString()).getTime()); | |
956 | +// } | |
957 | +// } | |
958 | + | |
959 | + // 파일리스트에 있는 파일한개 가져오기 | |
960 | + for (int i = 0; i < lsFiles.size(); i++) { | |
961 | + ChannelSftp.LsEntry lsEntry = lsFiles.get(i); | |
962 | + | |
963 | + SftpATTRS attrs = lsEntry.getAttrs(); | |
964 | + | |
965 | + // 시간변환 | |
966 | + SimpleDateFormat inFormat = new SimpleDateFormat ("EEE MMM d HH:mm:ss Z yyyy", Locale.ENGLISH); | |
967 | + Date date = inFormat.parse(attrs.getMtimeString()); | |
968 | + SimpleDateFormat outFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |
969 | + String formatDate = outFormat.format(date); | |
970 | + Date resultDate = outFormat.parse(formatDate); | |
971 | + | |
972 | + if(datasetDate.compareTo(resultDate) < 0) { | |
973 | + datasetAfterFileList = lsFiles.subList(i, lsFiles.size()); | |
974 | + break; | |
975 | + } | |
976 | + } | |
977 | + | |
978 | + if(!datasetAfterFileList.isEmpty()) { | |
979 | + for (ChannelSftp.LsEntry lsEntry : datasetAfterFileList) { | |
980 | + try(InputStream inputStream = channelSftp.get(fileInfo.getPath() + "/" + lsEntry.getFilename())) { | |
981 | + // 임시파일 생성 | |
982 | + File tempFile = File.createTempFile(String.valueOf(inputStream.hashCode()), "." + this.splitLastString(lsEntry.getFilename(), '.'), tempDir); | |
983 | + | |
984 | + // 임시파일 쓰기 | |
985 | + FileUtils.copyInputStreamToFile(inputStream, tempFile); | |
986 | + | |
987 | + //FileInfo를 임시파일 정보로 변경 | |
988 | + fileInfo.fileToFileInfo(tempFile); | |
989 | + | |
990 | + //임시파일 리스트 add | |
991 | + tempFiles.add(tempFile); | |
992 | + //파일읽기 리스트 add | |
993 | + files.add(fileInfo); | |
994 | + | |
995 | + } catch(Exception e) { | |
996 | + e.printStackTrace(); | |
997 | + } | |
998 | + } | |
999 | + } | |
1000 | + } | |
1001 | + } else { | |
1002 | + //자식파일이 없을때!! 구현해야함 | |
1003 | + } | |
1004 | + } catch(Exception e) { | |
1005 | + e.printStackTrace(); | |
1006 | + } | |
1007 | + } | |
1008 | + | |
1009 | + // 데이터셋 만들기 (파일 하나 밖에 처리 안 됨) | |
1010 | + Map<String, DataTable> dataTableMap = new LinkedHashMap<>(); | |
1011 | + for(FileInfo file : files) { | |
1012 | + try { | |
1013 | + dataTableMap = fileToDataset(file, limit); | |
1014 | + dataTables.add(dataTableMap.get(dataTableMap.keySet().toArray()[0])); | |
1015 | + } catch(Exception e) { | |
1016 | + e.printStackTrace(); | |
1017 | + } | |
1018 | + } | |
1019 | + | |
1020 | + // 데이터셋에 표출 컬럼명 추가 | |
1021 | + DataTable resultDataTable = new DataTable(); | |
1022 | + | |
1023 | + if(dataTables.size() > 0) resultDataTable = dataTables.get(0); | |
1024 | + | |
1025 | + List<ColumnData> columnDatas = resultDataTable.getColumnDatas(); | |
1026 | + | |
1027 | + for (ColumnData columnData : columnDatas) { | |
1028 | + columnData.setDisplyColumnNm(columnData.getOrginlColumnNm()); | |
1029 | + } | |
1030 | + | |
1031 | + // 데이터셋 인덱스 처리? | |
1032 | + /*if(fileInfo.getRowDataColumnIndex() > 0) { | |
1033 | + resultDataTable.setRowDataColumnIndex(fileInfo.getRowDataColumnIndex()); | |
1034 | + resultDataTable.setStartRowIndex(fileInfo.getStartRowIndex()); | |
1035 | + resultDataTable.setStartCellIndex(fileInfo.getStartCellIndex()); | |
1036 | + | |
1037 | + for(int i = 0 ; i < columnDatas.size() ; i++ ) { | |
1038 | + columnDatas.get(i).setDisplyColumnNm(resultDataTable.getColumnDatas().get(i).get(i).toString()); | |
1039 | + columnDatas.get(i).setOrginlColumnNm(resultDataTable.getRowData().get(0).get(i).toString()); | |
1040 | + } | |
1041 | + }*/ | |
1042 | + | |
1043 | +// customeResultMap.getResultData().put("dataTableMap", dataTableMap); | |
1044 | + | |
1045 | + try { | |
1046 | + DataTypeUtil.convertDataTableColumMeta(resultDataTable); // 데이터 컬럼에 메타 정보 삽입 | |
1047 | + } catch (Exception e) { | |
1048 | + e.printStackTrace(); | |
1049 | + } | |
1050 | + | |
1051 | + customeResultMap.getResultData().put("dataTableMap", resultDataTable); | |
1052 | + | |
1053 | + if (!tempFiles.isEmpty()) { // 임시파일 목록이 비어있지 않다면 | |
1054 | + for (File tempFile : tempFiles) { | |
1055 | + if(tempFile.exists()) { // 임시파일이 존재한다면 | |
1056 | + this.deleteTempFile(tempFile); // 임시파일 삭제 | |
1057 | + } | |
1058 | + } | |
1059 | + } | |
1060 | + | |
1061 | + return customeResultMap; | |
1062 | + } | |
1063 | + | |
1064 | + | |
1065 | + /** | |
1066 | + * 루트 폴더 설정 | |
1067 | + * | |
1068 | + * @author 김성훈 | |
1069 | + * @since 2024.01.04 | |
1070 | + */ | |
1071 | + public String rootPath(String path) { | |
1072 | + if (path == null || path.trim().isEmpty()) { | |
1073 | + path = "#"; | |
1074 | + } | |
1075 | + if ("#".equals(path)) { | |
1076 | + path = "/home"; | |
1077 | + } | |
1078 | + return path; | |
1079 | + } | |
1080 | + | |
1081 | + /** | |
1082 | + * 경로 및 확장자 추출 | |
1083 | + * | |
1084 | + * @author 김성훈 | |
1085 | + * @since 2024.01.04 | |
1086 | + */ | |
1087 | + public String splitLastString(String text, char deliminator) { | |
1088 | + int index = text.lastIndexOf(deliminator); | |
1089 | + if(index > 0) { | |
1090 | + return text.substring(index + 1); | |
1091 | + } | |
1092 | + return text; | |
1093 | + } | |
1094 | + | |
1095 | + /** | |
1096 | + * 부모파일경로 찾기 | |
1097 | + * | |
1098 | + * @author 김성훈 | |
1099 | + * @since 2024.01.04 | |
1100 | + */ | |
1101 | + public String parentPath(String path) { | |
1102 | + int index = path.lastIndexOf("/"); | |
1103 | + return path.substring(0,index); | |
1104 | + } | |
1105 | + | |
1106 | + /** | |
1107 | + * @author 김성훈 | |
1108 | + * @since 2024.02.08 | |
1109 | + * | |
1110 | + * 디렉토리( or 파일) 존재 여부 | |
1111 | + */ | |
1112 | + public boolean exists(String path) { | |
1113 | + Vector ls = null; | |
1114 | + try { | |
1115 | + ls = channelSftp.ls(path); | |
1116 | + } catch (SftpException e) { | |
1117 | + if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) { | |
1118 | + return false; | |
1119 | + } | |
1120 | + } | |
1121 | + return ls != null && !ls.isEmpty(); | |
1122 | + } | |
1123 | + | |
1124 | + | |
1125 | + /** | |
1126 | + * @author 김성훈 | |
1127 | + * @since 2024.02.16 | |
1128 | + * | |
1129 | + * 파일 업로드, 다운로드 진행율(%) 표시 | |
1130 | + */ | |
1131 | + class Monitor implements SftpProgressMonitor { | |
1132 | + | |
1133 | + private long max = 0; //최대 | |
1134 | + private long count = 0; //계산을 위해 담아두는 변수 | |
1135 | + private long percent = 0; //퍼센트 | |
1136 | + | |
1137 | + @Override | |
1138 | + public void init(int op, String src, String dest, long max) { //설정 | |
1139 | + | |
1140 | + this.max = max; | |
1141 | + } | |
1142 | + | |
1143 | + @Override | |
1144 | + public void end() { | |
1145 | + //종료시 할 행동 | |
1146 | + } | |
1147 | + | |
1148 | + @Override | |
1149 | + public boolean count(long bytes) { | |
1150 | + this.count += bytes; //전송한 바이트를 더한다. | |
1151 | + long percentNow = this.count*100/max; //현재값에서 최대값을 뺀후 | |
1152 | + if(percentNow>this.percent){ //퍼센트보다 크면 | |
1153 | + this.percent = percentNow; | |
1154 | + } | |
1155 | + return true;//기본값은 false이며 false인 경우 count메소드를 호출하지 않는다. | |
1156 | + } | |
1157 | + } | |
1158 | + | |
1159 | + /** | |
1160 | + * @author 하석형 | |
1161 | + * @since 2024.04.25 | |
1162 | + * | |
1163 | + * 파일 이동 복사 시작 | |
1164 | + */ | |
1165 | + public void inputMoveCopy(ConnectionVO.Move move) throws Exception { | |
1166 | + /** 호스트서버 -> 로컬 임시파일 다운로드 */ | |
1167 | + //임시 파일 저장 경로 | |
1168 | + String tempPath = SystemCode.FileUploadPath.TEMP_ABSOLUTE_PATH.getOSFileUploadPath(); | |
1169 | + | |
1170 | + //임시파일 저장 폴더 없으면 생성 | |
1171 | + File tempDir = new File(tempPath); | |
1172 | + if (tempDir.exists() == false) { | |
1173 | + tempDir.mkdirs(); | |
1174 | + } | |
1175 | + | |
1176 | + File newFile = null; // 최종 임시파일 | |
1177 | + | |
1178 | + try(InputStream inputStream = channelSftp.get(move.getPath())) { | |
1179 | + // 임시파일 생성 | |
1180 | + File tempFile = File.createTempFile(String.valueOf(inputStream.hashCode()), "." + move.getExtension(), tempDir); | |
1181 | + // 임시파일은 복사 후 삭제할거기 때문에 기존 파일명을 그대로 임시파일로 사용해도 문제없음 | |
1182 | +// File tempFile = File.createTempFile(move.getFileName(), "." + move.getExtension(), tempDir); | |
1183 | + | |
1184 | + // 임시파일 쓰기 | |
1185 | + FileUtils.copyInputStreamToFile(inputStream, tempFile); | |
1186 | + | |
1187 | + // 임시파일명을 기존 파일명으로 변경 | |
1188 | + newFile = new File(tempDir, move.getFileName()); | |
1189 | + boolean renamed = tempFile.renameTo(newFile); | |
1190 | + if (!renamed) { | |
1191 | + throw new IOException("임시 파일명 변경 실패"); | |
1192 | + } | |
1193 | + | |
1194 | + /** 로컬 -> 호스트서버 파일 업로드 */ | |
1195 | + // 업로드할 경로 | |
1196 | + String filePath = move.getMovePath() + "/" + move.getFileName(); | |
1197 | + | |
1198 | + try(InputStream uploadInputStream = new FileInputStream(newFile.getAbsolutePath())) { | |
1199 | + // 파일 업로드 | |
1200 | + channelSftp.put(uploadInputStream, filePath, new Monitor()); | |
1201 | + } | |
1202 | + | |
1203 | + } catch(Exception e) { | |
1204 | + e.printStackTrace(); | |
1205 | + throw new IOException(); | |
1206 | + } finally { | |
1207 | + // 로컬 임시파일 삭제 | |
1208 | + this.deleteTempFile(newFile); | |
1209 | + } | |
1210 | + } | |
1211 | + | |
1212 | + /** | |
1213 | + * @author 하석형 | |
1214 | + * @since 2024.04.26 | |
1215 | + * | |
1216 | + * 로컬 임시파일 삭제 | |
1217 | + */ | |
1218 | + public void deleteTempFile(File file) { | |
1219 | + if (file != null && file.exists()) { | |
1220 | + try { | |
1221 | + Files.delete(file.toPath()); | |
1222 | + } catch (IOException e) { | |
1223 | + System.err.println("임시 파일 삭제 실패: " + file.toPath()); | |
1224 | + } | |
1225 | + } | |
1226 | + } | |
1227 | + | |
1228 | + /** | |
1229 | + * @author 하석형 | |
1230 | + * @since 2024.04.26 | |
1231 | + * | |
1232 | + * 파일 쓰기 | |
1233 | + */ | |
1234 | + public CustomeResultMap fileWrite(JobItm jobItm) { | |
1235 | + CustomeResultMap customeResultMap = new CustomeResultMap(); | |
1236 | + SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |
1237 | + | |
1238 | + | |
1239 | + // 빈 파일 인스턴스 생성 | |
1240 | +// FileInfo fileInfo = new FileInfo(); | |
1241 | + ObjectMapper objectMapper = new ObjectMapper(); | |
1242 | + FileInfo fileInfo = objectMapper.convertValue(jobItm.getItm(), FileInfo.class); | |
1243 | + // 빈 데이터테이블 인스턴스 생성 | |
1244 | + DataTable dataTable = new DataTable(); | |
1245 | + | |
1246 | +// fileInfo = (FileInfo) jobItm.getItm(); | |
1247 | + dataTable = jobItm.getDataTable(); | |
1248 | + | |
1249 | + String suffix = ""; | |
1250 | + | |
1251 | + // 데이터명 뒤에 날짜 Suffix 처리 | |
1252 | + if(fileInfo.isStreOptn()) { | |
1253 | + suffix = StringUtil.getTodayaddMonth(fileInfo.getSuffix(), "month", fileInfo.getAddMonth()); | |
1254 | + } | |
1255 | + | |
1256 | + String fileName = removeFileExtension(fileInfo.getFileName()); | |
1257 | + | |
1258 | + // 생성된 파일 PATH | |
1259 | +// String path = fileInfo.getPath() + "/" + fileName + suffix + "." + fileInfo.getFileFom(); | |
1260 | + String path = fileInfo.getPath() + "/" + fileName + suffix + ".xlsx"; // 현재 xlsx만 지원 | |
1261 | + | |
1262 | +// String path = "C:\\Taken_BI_Manager" + File.separator + fileName + suffix + "." + fileInfo.getFileFom(); // 테스트 로컬 파일 | |
1263 | + | |
1264 | + // 임시 테이블명 처리 | |
1265 | + jobItm.getDataTable().setDatasetSj("upload"); | |
1266 | + | |
1267 | + // 엑셀파일로 파일 저장 | |
1268 | + XSSFWorkbook xlsWb = null; | |
1269 | + | |
1270 | + FileOutputStream fileOut = null; | |
1271 | + | |
1272 | + try { | |
1273 | +// xlsWb = dataTableService.getDataTableExcelDownload(jobItm.getDataTable()); | |
1274 | + xlsWb = this.getDataTableExcelDownload(jobItm.getDataTable()); | |
1275 | + /*File file = new File(path); | |
1276 | + FileOutputStream fileOut = new FileOutputStream(file); | |
1277 | + xlsWb.write(fileOut); | |
1278 | + fileOut.close();*/ | |
1279 | + try(InputStream inputStream = channelSftp.get(fileInfo.getPath())) { | |
1280 | + // 임시파일 생성 | |
1281 | +// File tempFile = File.createTempFile(String.valueOf(inputStream.hashCode()), "." + fileInfo.getExtension()); | |
1282 | + File tempFile = File.createTempFile(String.valueOf(inputStream.hashCode()), ".xlsx"); // 현재 xlsx만 지원 | |
1283 | + fileOut = new FileOutputStream(tempFile); | |
1284 | + xlsWb.write(fileOut); | |
1285 | + xlsWb.close(); | |
1286 | + | |
1287 | + try(InputStream uploadInputStream = new FileInputStream(tempFile.getAbsolutePath())) { | |
1288 | + // 파일 업로드 | |
1289 | + channelSftp.put(uploadInputStream, path, new Monitor()); | |
1290 | + } | |
1291 | + } | |
1292 | + | |
1293 | +// channelSftp.put(fileOut.toString(), path, new Monitor()); | |
1294 | + | |
1295 | + } catch (Exception e) { | |
1296 | + e.printStackTrace(); | |
1297 | + customeResultMap.getCheckMessage().setMessage("오류발생. 잠시후 다시 시도해주세요."); | |
1298 | + customeResultMap.getCheckMessage().setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
1299 | + } | |
1300 | + | |
1301 | + customeResultMap.getResultData().put("dataTableMap", null); | |
1302 | + | |
1303 | + return customeResultMap; | |
1304 | + } | |
1305 | + | |
1306 | + /** | |
1307 | + * @author 하석형 | |
1308 | + * @since 2024.04.26 | |
1309 | + * | |
1310 | + * 파일명 확장자 제거 | |
1311 | + */ | |
1312 | + public static String removeFileExtension(String fileName) { | |
1313 | + // 마지막 '.'의 위치를 찾음 | |
1314 | + int lastIndexOfDot = fileName.lastIndexOf("."); | |
1315 | + | |
1316 | + // '.'이 없거나 파일명의 맨 마지막에 위치한다면 확장자가 없는 것으로 간주, 원본 문자열 반환 | |
1317 | + if (lastIndexOfDot == -1 || lastIndexOfDot == fileName.length() - 1) { | |
1318 | + return fileName; | |
1319 | + } | |
1320 | + | |
1321 | + // '.' 이전까지의 문자열(확장자 제외)을 반환 | |
1322 | + return fileName.substring(0, lastIndexOfDot); | |
1323 | + } | |
1324 | + | |
1325 | + /** | |
1326 | + * @author 하석형 | |
1327 | + * @since 2024.04.26 | |
1328 | + * | |
1329 | + * 데이터테이블 엑셀화 | |
1330 | + */ | |
1331 | + public XSSFWorkbook getDataTableExcelDownload (DataTable dataTable) throws Exception { | |
1332 | + XSSFWorkbook xlsWb = new XSSFWorkbook(); | |
1333 | + | |
1334 | + if(dataTable.getTableNmKr() == null) { | |
1335 | + dataTable.setTableNmKr("데이터테이블"); | |
1336 | + } | |
1337 | + Sheet sheet = xlsWb.createSheet(dataTable.getTableNmKr()); | |
1338 | + | |
1339 | + int rowIdx = 0; | |
1340 | + | |
1341 | + //0행 0열 | |
1342 | + Row row = null; | |
1343 | + Cell cell = null; | |
1344 | + | |
1345 | + row = sheet.createRow(rowIdx++); | |
1346 | + for (int i = 0; i < dataTable.getColumnDatas().size(); i++) { | |
1347 | + cell = row.createCell(i); | |
1348 | + | |
1349 | + String columnName = dataTable.getColumnDatas().get(i).getDisplyColumnNm(); | |
1350 | + if (StringUtil.isEmpty(columnName)) { | |
1351 | + columnName = dataTable.getColumnDatas().get(i).getOrginlColumnNm(); | |
1352 | + } | |
1353 | + | |
1354 | + cell.setCellValue(columnName); | |
1355 | + cell.setCellStyle(getCellStyle(xlsWb, "head")); | |
1356 | + } | |
1357 | + | |
1358 | + for (int i = 0; i < dataTable.getRowData().size(); i++) { | |
1359 | + row = sheet.createRow(rowIdx++); | |
1360 | + for (int j = 0; j < dataTable.getRowData().get(i).size(); j++) { | |
1361 | + cell = row.createCell(j); | |
1362 | +// cell.setCellValue(dataTable.getRowData().get(i).get(j)); | |
1363 | + | |
1364 | + Object value = dataTable.getRowData().get(i).get(j); | |
1365 | + cell.setCellValue(value.toString()); | |
1366 | + } | |
1367 | + } | |
1368 | + | |
1369 | + return xlsWb; | |
1370 | + } | |
1371 | + | |
1372 | + public CellStyle getCellStyle(XSSFWorkbook xlsWb, String kind) { | |
1373 | + CellStyle cellStyle = xlsWb.createCellStyle(); | |
1374 | + cellStyle.setAlignment(HorizontalAlignment.CENTER); //가운데 정렬 | |
1375 | + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); //중앙 정렬 | |
1376 | + | |
1377 | + if(kind.equals("head")) { | |
1378 | + cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); //노란색 | |
1379 | + cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); //색상 패턴처리 | |
1380 | + } | |
1381 | + | |
1382 | + return cellStyle; | |
1383 | + } | |
1384 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/StringUtil.java
... | ... | @@ -0,0 +1,713 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import java.io.UnsupportedEncodingException; | |
6 | +import java.sql.Timestamp; | |
7 | +import java.text.SimpleDateFormat; | |
8 | +import java.util.ArrayList; | |
9 | +import java.util.Calendar; | |
10 | +import java.util.Date; | |
11 | +import java.util.GregorianCalendar; | |
12 | +import java.util.Locale; | |
13 | +import java.util.Random; | |
14 | + | |
15 | +import org.slf4j.Logger; | |
16 | +import org.slf4j.LoggerFactory; | |
17 | +import org.springframework.boot.web.servlet.server.Encoding.Type; | |
18 | + | |
19 | + | |
20 | +/** | |
21 | + * @author 최정우 | |
22 | + * @since 2019.11.13 | |
23 | + * | |
24 | + * 문자열과 관련된 기능을 정의 해놓은 Util입니다. | |
25 | + */ | |
26 | +public class StringUtil { | |
27 | + | |
28 | + private static final Logger LOGGER = LoggerFactory.getLogger(StringUtil.class); | |
29 | + | |
30 | + public static final String NULL_TEXT = "NULL"; | |
31 | + | |
32 | + public static String toString(Object obj) { | |
33 | + if (obj == null) { | |
34 | + return null; | |
35 | + } else { | |
36 | + try { | |
37 | + return obj.toString(); | |
38 | + } catch (Exception e) { | |
39 | + return null; | |
40 | + } | |
41 | + } | |
42 | + } | |
43 | + | |
44 | + public static String toStringNotNull(Object obj) { | |
45 | + if (obj == null) { | |
46 | + return ""; | |
47 | + } else { | |
48 | + try { | |
49 | + return obj.toString(); | |
50 | + } catch (Exception e) { | |
51 | + return ""; | |
52 | + } | |
53 | + } | |
54 | + } | |
55 | + | |
56 | + /** | |
57 | + * @author 최정우 | |
58 | + * @since 2020.11.26 | |
59 | + * | |
60 | + * 객체를 문자열로 바꾼 후, 문자열 길이 반환 | |
61 | + */ | |
62 | + public static int stringLength(Object obj) { | |
63 | + if (obj == null) { | |
64 | + return 0; | |
65 | + } else { | |
66 | + try { | |
67 | + return obj.toString().length(); | |
68 | + } catch (Exception e) { | |
69 | + return 0; | |
70 | + } | |
71 | + } | |
72 | + } | |
73 | + | |
74 | + /** | |
75 | + * @author 최정우 | |
76 | + * @since 2020.11.26 | |
77 | + * | |
78 | + * 문자열이 Null or null or NULL인 경우 실제 null값 세팅 | |
79 | + */ | |
80 | + public static boolean isNullText(String text) { | |
81 | + if (isEmpty(text) == false && text.toUpperCase().equals(NULL_TEXT)) { | |
82 | + return true; | |
83 | + } else { | |
84 | + return false; | |
85 | + } | |
86 | + } | |
87 | + | |
88 | + /** | |
89 | + * @author 최정우 | |
90 | + * @since 2019.11.13 | |
91 | + * | |
92 | + * 빈 문자열 검사 | |
93 | + */ | |
94 | + public static boolean isEmpty(String text) { | |
95 | + return text == null || text.trim().length() == 0; | |
96 | + } | |
97 | + | |
98 | + /** | |
99 | + * @author 최정우 | |
100 | + * @since 2019.11.13 | |
101 | + * | |
102 | + * indexOf - 문자 검색 후, 해당 문자의 위치(index)반환 | |
103 | + */ | |
104 | + public static int indexOf(String text, String searchText) { | |
105 | + if (text == null || searchText == null) { | |
106 | + return -1; | |
107 | + } | |
108 | + return text.indexOf(searchText); | |
109 | + } | |
110 | + | |
111 | + /** | |
112 | + * @author 최정우 | |
113 | + * @since 2019.11.13 | |
114 | + * | |
115 | + * lastIndexOf - 문자 검색 후, 해당 문자의 위치(index)반환 | |
116 | + */ | |
117 | + public static int lastIndexOf(String text, String searchText) { | |
118 | + if (text == null || searchText == null) { | |
119 | + return -1; | |
120 | + } | |
121 | + return text.lastIndexOf(searchText); | |
122 | + } | |
123 | + | |
124 | + /** | |
125 | + * @author 최정우 | |
126 | + * @since 2019.11.13 | |
127 | + * | |
128 | + * substringBetween - 특정 문자열 사이에 값을 뽑아내는 메서드 | |
129 | + */ | |
130 | + public static String substringBetween(String text, String startText, String endText) { | |
131 | + if (isEmpty(text) == true || isEmpty(startText) == true || isEmpty(endText) == true) { | |
132 | + return null; | |
133 | + } | |
134 | + text = text.toLowerCase(); | |
135 | + startText = startText.toLowerCase(); | |
136 | + endText = endText.toLowerCase(); | |
137 | + | |
138 | + int start = text.indexOf(startText); | |
139 | + if (start != -1) { | |
140 | + int end = text.indexOf(endText, start + startText.length()); | |
141 | + if (end != -1) { | |
142 | + return text.substring(start + startText.length(), end); | |
143 | + } | |
144 | + } | |
145 | + return null; | |
146 | + } | |
147 | + | |
148 | + /** | |
149 | + * @author 최정우 | |
150 | + * @since 2019.11.13 | |
151 | + * | |
152 | + * 모든 공백 제거 | |
153 | + */ | |
154 | + public static String removeSpace(String text) { | |
155 | + if (isEmpty(text)) { | |
156 | + return text; | |
157 | + } | |
158 | + int length = text.length(); | |
159 | + char[] newCharList = new char[length]; | |
160 | + int count = 0; | |
161 | + for (int i = 0; i < length; i++) { | |
162 | + if (Character.isWhitespace(text.charAt(i)) == false) { | |
163 | + newCharList[count++] = text.charAt(i); | |
164 | + } | |
165 | + } | |
166 | + if (count == length) { | |
167 | + return text; | |
168 | + } | |
169 | + | |
170 | + return new String(newCharList, 0, count); | |
171 | + } | |
172 | + | |
173 | + | |
174 | + | |
175 | + /** | |
176 | + * @author 최정우 | |
177 | + * @since 2019.11.13 | |
178 | + * | |
179 | + * 소문자 변환 | |
180 | + */ | |
181 | + public static String lowerCase(String text) { | |
182 | + if (isEmpty(text) == true) { | |
183 | + return text; | |
184 | + } else { | |
185 | + return text.toLowerCase(); | |
186 | + } | |
187 | + } | |
188 | + | |
189 | + /** | |
190 | + * 대문자 변환 | |
191 | + */ | |
192 | + public static String upperCase(String text) { | |
193 | + if (isEmpty(text) == true) { | |
194 | + return text; | |
195 | + } else { | |
196 | + return text.toUpperCase(); | |
197 | + } | |
198 | + } | |
199 | + | |
200 | + /** | |
201 | + * @author 최정우 | |
202 | + * @since 2019.11.13 | |
203 | + * | |
204 | + * 현재날짜(년,월,일)를 구하는 기능 | |
205 | + */ | |
206 | + public static String getToday() { | |
207 | + String pattern = "yyyy-MM-dd"; | |
208 | + SimpleDateFormat dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
209 | + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); | |
210 | + return dateFormat.format(timestamp.getTime()); | |
211 | + } | |
212 | + | |
213 | + /** | |
214 | + * @author 최정우 | |
215 | + * @since 2019.11.13 | |
216 | + * | |
217 | + * 현재날짜(년,월,일)를 구하는 기능 | |
218 | + */ | |
219 | + public static String getToday(String pattern) { | |
220 | + String defaultPattern = "yyyy-MM-dd"; | |
221 | + if (isEmpty(pattern) == true) { | |
222 | + pattern = defaultPattern; | |
223 | + } | |
224 | + | |
225 | + SimpleDateFormat dateFormat = null; | |
226 | + try { | |
227 | + dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
228 | + } catch (Exception e) { | |
229 | + dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA); | |
230 | + } | |
231 | + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); | |
232 | + return dateFormat.format(timestamp.getTime()); | |
233 | + } | |
234 | + | |
235 | + | |
236 | + /** | |
237 | + * @author 김성원 | |
238 | + * @since 2019.11.13 | |
239 | + * | |
240 | + * 현재날짜(년,월,일)에 특정 날짜 + - | |
241 | + */ | |
242 | + public static String getTodayaddMonth(String pattern, String type, int date) { | |
243 | + String defaultPattern = "yyyy-MM-dd"; | |
244 | + if (isEmpty(pattern) == true) { | |
245 | + pattern = defaultPattern; | |
246 | + } | |
247 | + | |
248 | + SimpleDateFormat dateFormat = null; | |
249 | + try { | |
250 | + dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
251 | + } catch (Exception e) { | |
252 | + dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA); | |
253 | + } | |
254 | + | |
255 | + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); | |
256 | + Calendar cal = Calendar.getInstance(); | |
257 | + if(type.equals("year")) { | |
258 | + cal.add(Calendar.YEAR, date); | |
259 | + }else if(type.equals("month")) { | |
260 | + cal.add(Calendar.MONTH, date); | |
261 | + }else if(type.equals("day")) { | |
262 | + cal.add(Calendar.DATE, date); | |
263 | + } | |
264 | + | |
265 | + return dateFormat.format(cal.getTime()); | |
266 | + } | |
267 | + | |
268 | + /** | |
269 | + * @author 최정우 | |
270 | + * @since 2019.11.13 | |
271 | + * | |
272 | + * 현재날짜(년,월,일)를 구하는 기능 | |
273 | + */ | |
274 | + public static String getToday(String yearSuffix, String monthSuffix, String daySuffix) { | |
275 | + String defaultPattern = "yyyy년MM월dd일"; | |
276 | + if (isEmpty(yearSuffix) == true) { | |
277 | + yearSuffix = ""; | |
278 | + } | |
279 | + if (isEmpty(monthSuffix) == true) { | |
280 | + monthSuffix = ""; | |
281 | + } | |
282 | + if (isEmpty(daySuffix) == true) { | |
283 | + daySuffix = ""; | |
284 | + } | |
285 | + | |
286 | + String pattern = "yyyy" + yearSuffix + "MM" + monthSuffix + "dd" + daySuffix; | |
287 | + | |
288 | + SimpleDateFormat dateFormat = null; | |
289 | + try { | |
290 | + dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
291 | + } catch (Exception e) { | |
292 | + dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA); | |
293 | + } | |
294 | + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); | |
295 | + return dateFormat.format(timestamp.getTime()); | |
296 | + } | |
297 | + | |
298 | + /** | |
299 | + * @author 최정우 | |
300 | + * @since 2019.11.13 | |
301 | + * | |
302 | + * 17자리의 현재일시를 구하는 기능 | |
303 | + */ | |
304 | + public static String getDateTime() { | |
305 | + // 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초)) | |
306 | + String pattern = "yyyyMMddHHmmssSSS"; | |
307 | + SimpleDateFormat dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
308 | + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); | |
309 | + return dateFormat.format(timestamp.getTime()); | |
310 | + } | |
311 | + | |
312 | + /** | |
313 | + * @author 최정우 | |
314 | + * @since 2019.11.13 | |
315 | + * | |
316 | + * 원하는 패턴의 현재일시 구하는 기능 | |
317 | + */ | |
318 | + public static String getDateTime(String pattern) { | |
319 | + // 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초)) | |
320 | + String defaultPattern = "yyyyMMddHHmmssSSS"; | |
321 | + if (isEmpty(pattern)) { | |
322 | + pattern = defaultPattern; | |
323 | + } | |
324 | + SimpleDateFormat dateFormat = null; | |
325 | + try { | |
326 | + dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
327 | + } catch (Exception e) { | |
328 | + dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA); | |
329 | + } | |
330 | + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); | |
331 | + return dateFormat.format(timestamp.getTime()); | |
332 | + } | |
333 | + | |
334 | + /** | |
335 | + * @author 최정우 | |
336 | + * @since 2019.11.13 | |
337 | + * | |
338 | + * 현재 일시 - addDay => 원하는 패턴의 일시를 구하는 기능 | |
339 | + */ | |
340 | + public static String getDateTime(String pattern, int addDay) { | |
341 | + // 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초)) | |
342 | + String defaultPattern = "yyyyMMddHHmmssSSS"; | |
343 | + if (pattern == null) { | |
344 | + pattern = defaultPattern; | |
345 | + } | |
346 | + SimpleDateFormat dateFormat = null; | |
347 | + try { | |
348 | + dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
349 | + } catch (Exception e) { | |
350 | + dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA); | |
351 | + } | |
352 | + Calendar cal = new GregorianCalendar(); | |
353 | + cal.add(Calendar.DATE, addDay); | |
354 | + Date date = cal.getTime(); | |
355 | + return dateFormat.format(date.getTime()); | |
356 | + } | |
357 | + | |
358 | + /** | |
359 | + * @author 최정우 | |
360 | + * @since 2019.11.13 | |
361 | + * | |
362 | + * 현재 일시 - addDay => 원하는 패턴의 일시를 구하는 기능 | |
363 | + */ | |
364 | + public static String getDateTime(String pattern, int addDay, int addHour, int addMin, int addSec) { | |
365 | + // 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초)) | |
366 | + String defaultPattern = "yyyyMMddHHmmssSSS"; | |
367 | + if (pattern == null) { | |
368 | + pattern = defaultPattern; | |
369 | + } | |
370 | + SimpleDateFormat dateFormat = null; | |
371 | + try { | |
372 | + dateFormat = new SimpleDateFormat(pattern, Locale.KOREA); | |
373 | + } catch (Exception e) { | |
374 | + dateFormat = new SimpleDateFormat(defaultPattern, Locale.KOREA); | |
375 | + } | |
376 | + Calendar cal = new GregorianCalendar(); | |
377 | + cal.add(Calendar.DATE, addDay); | |
378 | + cal.add(Calendar.HOUR, addHour); | |
379 | + cal.add(Calendar.MINUTE, addMin); | |
380 | + cal.add(Calendar.SECOND, addSec); | |
381 | + Date date = cal.getTime(); | |
382 | + return dateFormat.format(date.getTime()); | |
383 | + } | |
384 | + | |
385 | + /** | |
386 | + * @author 최정우 | |
387 | + * @since 2019.11.13 | |
388 | + * | |
389 | + * 현재 일시(17자리)와, 랜덤숫자(4자리)를 이용하여 키값 생성 | |
390 | + */ | |
391 | + public static String getCreateKey (String prefix) { | |
392 | + int random = new Random().nextInt(9999); | |
393 | + String result = prefix + "_" + getDateTime() + "_" + numberToText(random, 4); | |
394 | + return result; | |
395 | + } | |
396 | + | |
397 | + /** | |
398 | + * @author 최정우 | |
399 | + * @since 2019.11.13 | |
400 | + * | |
401 | + * 문자열이 Date문자열(yyyy-MM-dd)로 포맷 가능한지 | |
402 | + * text: 문자열 | |
403 | + * pattern: 문자열의 날짜 패턴 | |
404 | + */ | |
405 | + public static boolean isDate(String text, String pattern) { | |
406 | + try { | |
407 | + Date date = new SimpleDateFormat(pattern).parse(text); | |
408 | + text = new SimpleDateFormat("yyyy-MM-dd").format(date); | |
409 | + return true; | |
410 | + } catch (java.text.ParseException e) { | |
411 | + // TODO Auto-generated catch block | |
412 | + return false; | |
413 | + } | |
414 | + } | |
415 | + | |
416 | + /** | |
417 | + * @author 최정우 | |
418 | + * @since 2019.11.13 | |
419 | + * | |
420 | + * 문자열을 날짜형태로 Convert | |
421 | + * text: 문자열 | |
422 | + * pattern: 문자열의 날짜 패턴 | |
423 | + * newPattern: 해당 문자열을 Converting할 날짜 패턴 | |
424 | + */ | |
425 | + public static String textToDateText (String text, String pattern, String newPattern) { | |
426 | + String defaultPattern = "yyyy-MM-dd"; | |
427 | + if (isEmpty(newPattern) == true) { | |
428 | + newPattern = defaultPattern; | |
429 | + } | |
430 | + | |
431 | + SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); | |
432 | + Date date = new Date(); | |
433 | + try { | |
434 | + date = dateFormat.parse(text); | |
435 | + dateFormat.applyPattern(newPattern); | |
436 | + return dateFormat.format(date); | |
437 | + } catch (Exception e) { | |
438 | + //e.printStackTrace(); | |
439 | + return text; | |
440 | + } | |
441 | + } | |
442 | + | |
443 | + /** | |
444 | + * @author 최정우 | |
445 | + * @since 2019.11.13 | |
446 | + * | |
447 | + * 숫자 -> 문자열 -> 문자열 길이가 length보다 작을 때, length길이 만큼될 수 있도록 앞에 '0'을 붙여줌 | |
448 | + */ | |
449 | + public static String numberToText (int number, int length) { | |
450 | + String text = Integer.toString(number); | |
451 | + if (text.length() < length) { | |
452 | + int emptyLength = length - text.length(); | |
453 | + for (int i = 0; i < emptyLength; i++) { | |
454 | + text = "0" + text; | |
455 | + } | |
456 | + } | |
457 | + return text; | |
458 | + } | |
459 | + | |
460 | + /** | |
461 | + * @author 최정우 | |
462 | + * @since 2019.11.13 | |
463 | + * | |
464 | + * 문자열이 지정한 길이를 초과했을때 해당 문자열을 삭제하는 메서드 | |
465 | + * @param text 원본 문자열 배열 | |
466 | + * @param maxLength 지정길이 | |
467 | + * @return 지정길이로 자른 문자열 | |
468 | + */ | |
469 | + public static String cutString(String text, int maxLength) { | |
470 | + String result = null; | |
471 | + if (text != null) { | |
472 | + if (text.length() > maxLength) { | |
473 | + result = text.substring(0, maxLength); | |
474 | + } else | |
475 | + result = text; | |
476 | + } | |
477 | + return result; | |
478 | + } | |
479 | + | |
480 | + | |
481 | + /** | |
482 | + * @author 최정우 | |
483 | + * @since 2019.11.13 | |
484 | + * | |
485 | + * 문자열이 지정한 길이를 초과했을때 지정한길이에다가 해당 문자열을 붙여주는 메서드. | |
486 | + * @param text 원본 문자열 배열 | |
487 | + * @param addText 더할문자열 | |
488 | + * @param maxLength 지정길이 | |
489 | + * @return 지정길이로 잘라서 더할분자열 합친 문자열 | |
490 | + */ | |
491 | + public static String cutString(String text, String addText, int maxLength) { | |
492 | + String result = null; | |
493 | + if (text != null) { | |
494 | + if (text.length() > maxLength) { | |
495 | + result = text.substring(0, maxLength) + addText; | |
496 | + } else | |
497 | + result = text; | |
498 | + } | |
499 | + return result; | |
500 | + } | |
501 | + | |
502 | + | |
503 | + /** | |
504 | + * @author 최정우 | |
505 | + * @since 2019.11.13 | |
506 | + * | |
507 | + * <p>기준 문자열에 포함된 모든 대상 문자(char)를 제거한다.</p> | |
508 | + * | |
509 | + * <pre> | |
510 | + * StringUtil.remove(null, *) = null | |
511 | + * StringUtil.remove("", *) = "" | |
512 | + * StringUtil.remove("queued", 'u') = "qeed" | |
513 | + * StringUtil.remove("queued", 'z') = "queued" | |
514 | + * </pre> | |
515 | + * | |
516 | + * @param str 입력받는 기준 문자열 | |
517 | + * @param remove 입력받는 문자열에서 제거할 대상 문자열 | |
518 | + * @return 제거대상 문자열이 제거된 입력문자열. 입력문자열이 null인 경우 출력문자열은 null | |
519 | + */ | |
520 | + public static String remove(String text, char remove) { | |
521 | + if (isEmpty(text) || text.indexOf(remove) == -1) { | |
522 | + return text; | |
523 | + } | |
524 | + char[] chars = text.toCharArray(); | |
525 | + int pos = 0; | |
526 | + for (int i = 0; i < chars.length; i++) { | |
527 | + if (chars[i] != remove) { | |
528 | + chars[pos++] = chars[i]; | |
529 | + } | |
530 | + } | |
531 | + | |
532 | + return new String(chars, 0, pos); | |
533 | + } | |
534 | + | |
535 | + | |
536 | + /** | |
537 | + * @author 최정우 | |
538 | + * @since 2019.11.13 | |
539 | + * | |
540 | + * 원본 문자열의 포함된 특정 문자열을 새로운 문자열로 변환하는 메서드 | |
541 | + * @param source 원본 문자열 | |
542 | + * @param subject 원본 문자열에 포함된 특정 문자열 | |
543 | + * @param object 변환할 문자열 | |
544 | + * @return sb.toString() 새로운 문자열로 변환된 문자열 | |
545 | + */ | |
546 | + public static String replace(String text, String subject, String object) { | |
547 | + StringBuffer rtnStr = new StringBuffer(); | |
548 | + String preStr = ""; | |
549 | + String nextStr = text; | |
550 | + String srcStr = text; | |
551 | + | |
552 | + while (srcStr.indexOf(subject) >= 0) { | |
553 | + preStr = srcStr.substring(0, srcStr.indexOf(subject)); | |
554 | + nextStr = srcStr.substring(srcStr.indexOf(subject) + subject.length(), srcStr.length()); | |
555 | + srcStr = nextStr; | |
556 | + rtnStr.append(preStr).append(object); | |
557 | + } | |
558 | + rtnStr.append(nextStr); | |
559 | + return rtnStr.toString(); | |
560 | + } | |
561 | + | |
562 | + /** | |
563 | + * @author 최정우 | |
564 | + * @since 2019.11.13 | |
565 | + * | |
566 | + * 원본 문자열의 포함된 특정 문자열 첫번째 한개만 새로운 문자열로 변환하는 메서드 | |
567 | + * @param source 원본 문자열 | |
568 | + * @param subject 원본 문자열에 포함된 특정 문자열 | |
569 | + * @param object 변환할 문자열 | |
570 | + * @return sb.toString() 새로운 문자열로 변환된 문자열 / source 특정문자열이 없는 경우 원본 문자열 | |
571 | + */ | |
572 | + public static String replaceOnce(String source, String subject, String object) { | |
573 | + StringBuffer rtnStr = new StringBuffer(); | |
574 | + String preStr = ""; | |
575 | + String nextStr = source; | |
576 | + if (source.indexOf(subject) >= 0) { | |
577 | + preStr = source.substring(0, source.indexOf(subject)); | |
578 | + nextStr = source.substring(source.indexOf(subject) + subject.length(), source.length()); | |
579 | + rtnStr.append(preStr).append(object).append(nextStr); | |
580 | + return rtnStr.toString(); | |
581 | + } else { | |
582 | + return source; | |
583 | + } | |
584 | + } | |
585 | + | |
586 | + /** | |
587 | + * @author 최정우 | |
588 | + * @since 2019.11.13 | |
589 | + * | |
590 | + * <code>subject</code>에 포함된 각각의 문자를 object로 변환한다. | |
591 | + * | |
592 | + * @param source 원본 문자열 | |
593 | + * @param subject 원본 문자열에 포함된 특정 문자열 | |
594 | + * @param object 변환할 문자열 | |
595 | + * @return sb.toString() 새로운 문자열로 변환된 문자열 | |
596 | + */ | |
597 | + public static String replaceChar(String source, String subject, String object) { | |
598 | + StringBuffer rtnStr = new StringBuffer(); | |
599 | + String preStr = ""; | |
600 | + String nextStr = source; | |
601 | + String srcStr = source; | |
602 | + | |
603 | + char chA; | |
604 | + | |
605 | + for (int i = 0; i < subject.length(); i++) { | |
606 | + chA = subject.charAt(i); | |
607 | + | |
608 | + if (srcStr.indexOf(chA) >= 0) { | |
609 | + preStr = srcStr.substring(0, srcStr.indexOf(chA)); | |
610 | + nextStr = srcStr.substring(srcStr.indexOf(chA) + 1, srcStr.length()); | |
611 | + srcStr = rtnStr.append(preStr).append(object).append(nextStr).toString(); | |
612 | + } | |
613 | + } | |
614 | + | |
615 | + return srcStr; | |
616 | + } | |
617 | + | |
618 | + /** | |
619 | + * @author 최정우 | |
620 | + * @since 2019.11.13 | |
621 | + * | |
622 | + * 문자열을 다양한 문자셋(EUC-KR[KSC5601],UTF-8..)을 사용하여 인코딩하는 기능 역으로 디코딩하여 원래의 문자열을 | |
623 | + * 복원하는 기능을 제공함 String temp = new String(문자열.getBytes("바꾸기전 인코딩"),"바꿀 인코딩"); | |
624 | + * String temp = new String(문자열.getBytes("8859_1"),"KSC5601"); => UTF-8 에서 | |
625 | + * EUC-KR | |
626 | + * | |
627 | + * @param text - 문자열 | |
628 | + * @param encoding - 원래의 인코딩된 값 | |
629 | + * @param decoding - 디코딩할 문자값 | |
630 | + * @return 인(디)코딩 문자열 | |
631 | + * @exception MyException | |
632 | + * @see | |
633 | + */ | |
634 | + public static String textDecoding(String text, String encoding, String decoding) { | |
635 | + if (text == null) { | |
636 | + return null; | |
637 | + } | |
638 | + | |
639 | + try { | |
640 | + text = new String(text.getBytes(encoding), decoding); | |
641 | + } catch (UnsupportedEncodingException e) { | |
642 | + text = null; | |
643 | + } | |
644 | + | |
645 | + return text; | |
646 | + } | |
647 | + | |
648 | + | |
649 | + /** | |
650 | + * @author 최정우 | |
651 | + * @since 2020.11.26 | |
652 | + * | |
653 | + * 문자열 특정 포맷팅으로 변환 ##-#### | |
654 | + */ | |
655 | + public static String formatConvert(String data, String format) { | |
656 | + | |
657 | + StringBuilder bf = new StringBuilder(); | |
658 | + | |
659 | + if(StringUtil.isEmpty(format) || StringUtil.isEmpty(data)) { | |
660 | + bf.append(data); | |
661 | + }else { | |
662 | + int num = data.length()-1; | |
663 | + for(int i = format.length()-1 ; i >= 0 ; i--) { | |
664 | + if(format.charAt(i) == '#') { | |
665 | + bf.insert(0, data.charAt(num--)); | |
666 | + }else { | |
667 | + bf.insert(0,format.charAt(i)); | |
668 | + } | |
669 | + } | |
670 | + } | |
671 | + | |
672 | + return bf.toString(); | |
673 | + } | |
674 | + | |
675 | + /** | |
676 | + * @author 김성원 | |
677 | + * @since 2022.07.06 | |
678 | + * | |
679 | + * 날짜형식 문자열 특정 포맷팅으로 변환 ##-#### | |
680 | + */ | |
681 | + public static String dateConvert(String date) { | |
682 | + | |
683 | + StringBuilder bf = new StringBuilder(); | |
684 | + | |
685 | + boolean dateForm = true; | |
686 | + | |
687 | + if(!date.contains("-") && date.length() > 4) { | |
688 | + dateForm = false; | |
689 | + } | |
690 | + | |
691 | + if(!StringUtil.isEmpty(date)) { | |
692 | + | |
693 | + String dateStr = date.replaceAll("[^0-9]", ""); | |
694 | + // 년도 처리 | |
695 | + if(dateStr.length() < 5) { | |
696 | + bf.append(date.substring(0,4)); | |
697 | + }else { | |
698 | + if(dateForm == true) { | |
699 | + bf.append(StringUtil.formatConvert(dateStr.substring(0,6),"####-##")); | |
700 | + }else { | |
701 | + bf.append(StringUtil.formatConvert(dateStr.substring(0,6),"####-##")); | |
702 | + //bf.append(dateStr.substring(0,4)); | |
703 | + //bf.append("년 "); | |
704 | + } | |
705 | + } | |
706 | + } | |
707 | + | |
708 | + return bf.toString(); | |
709 | + } | |
710 | + | |
711 | + | |
712 | + | |
713 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/bean/ApplicationContextProvider.java
... | ... | @@ -0,0 +1,45 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util.bean; | |
2 | + | |
3 | +import org.springframework.beans.BeansException; | |
4 | +import org.springframework.context.ApplicationContext; | |
5 | +import org.springframework.context.ApplicationContextAware; | |
6 | +import org.springframework.stereotype.Component; | |
7 | + | |
8 | +/** | |
9 | + * @author 최정우 | |
10 | + * @since 2019.11.17 | |
11 | + * | |
12 | + * Spring 컨테이너(ApplicationContext)에 접근하기 위한 Class 입니다. | |
13 | + * ApplicationContextAware 구현체 | |
14 | + */ | |
15 | +@Component | |
16 | +public class ApplicationContextProvider implements ApplicationContextAware { | |
17 | + | |
18 | + /** | |
19 | + * 해당 어플리케이션의 인스턴스(bean)들의 정보를 담은 객체 | |
20 | + */ | |
21 | + private static ApplicationContext applicationContext; | |
22 | + | |
23 | + /** | |
24 | + * @author 최정우 | |
25 | + * @since 2019.11.17 | |
26 | + * | |
27 | + * ApplicationContextAware를 구현하기 위한 메소드 | |
28 | + * Spring 구동 시, 해당 Class가 스캔 당하면 applicationContext 객체가 생성됨 | |
29 | + */ | |
30 | + @Override | |
31 | + public void setApplicationContext(ApplicationContext ctx) throws BeansException { | |
32 | + applicationContext = ctx; | |
33 | + } | |
34 | + | |
35 | + /** | |
36 | + * @author 최정우 | |
37 | + * @since 2019.11.17 | |
38 | + * | |
39 | + * applicationContext 객체 호출 | |
40 | + */ | |
41 | + public static ApplicationContext getApplicationContext() { | |
42 | + return applicationContext; | |
43 | + } | |
44 | + | |
45 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/bean/BeanUtil.java
... | ... | @@ -0,0 +1,42 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util.bean; | |
2 | + | |
3 | +import org.springframework.beans.BeansException; | |
4 | + | |
5 | +/** | |
6 | + * @author 최정우 | |
7 | + * @since 2020.11.25 | |
8 | + * | |
9 | + * ApplicationContextProvider에서 bean객체를 얻어 활용할 수 있도록 해주는 Util 입니다. | |
10 | + */ | |
11 | +public class BeanUtil { | |
12 | + | |
13 | + /** | |
14 | + * @author 최정우 | |
15 | + * @since 2019.11.17 | |
16 | + * | |
17 | + * 해당 어플리케이션에서 스프링 컨테이너가 관리하는 bean으로 등록된 객체를 이름으로 호출 | |
18 | + */ | |
19 | + public static Object getBean(String beanName) { | |
20 | + try { | |
21 | + return ApplicationContextProvider.getApplicationContext().getBean(beanName); | |
22 | + } catch (BeansException e) { | |
23 | + e.printStackTrace(); | |
24 | + return null; | |
25 | + } | |
26 | + } | |
27 | + | |
28 | + /** | |
29 | + * @author 최정우 | |
30 | + * @since 2019.11.17 | |
31 | + * | |
32 | + * 해당 어플리케이션에서 스프링 컨테이너가 관리하는 bean으로 등록된 객체를 객체의 타입으로 호출 | |
33 | + */ | |
34 | + public static Object getBean(Class<?> classType) { | |
35 | + try { | |
36 | + return ApplicationContextProvider.getApplicationContext().getBean(classType); | |
37 | + } catch (BeansException e) { | |
38 | + e.printStackTrace(); | |
39 | + return null; | |
40 | + } | |
41 | + } | |
42 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/reflection/ParentLastURLClassLoader.java
... | ... | @@ -0,0 +1,88 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util.reflection; | |
2 | + | |
3 | +import java.net.URL; | |
4 | +import java.net.URLClassLoader; | |
5 | + | |
6 | +/* | |
7 | + * 커스텀 URLClassLoder | |
8 | + * | |
9 | + * WAS(톰캣)에서 URLClassLoder로 작동시 외부 라이브러리에 있는 jar파일을 읽지 못함 | |
10 | + * 외부 라이브러리 class들을 먼저 읽기 위함 | |
11 | + */ | |
12 | +public class ParentLastURLClassLoader extends ClassLoader | |
13 | +{ | |
14 | + private ChildURLClassLoader childClassLoader; | |
15 | + | |
16 | + /** | |
17 | + * This class allows me to call findClass on a classloader | |
18 | + */ | |
19 | + private static class FindClassClassLoader extends ClassLoader | |
20 | + { | |
21 | + public FindClassClassLoader(ClassLoader parent) | |
22 | + { | |
23 | + super(parent); | |
24 | + } | |
25 | + | |
26 | + @Override | |
27 | + public Class<?> findClass(String name) throws ClassNotFoundException | |
28 | + { | |
29 | + return super.findClass(name); | |
30 | + } | |
31 | + } | |
32 | + | |
33 | + /** | |
34 | + * This class delegates (child then parent) for the findClass method for a URLClassLoader. | |
35 | + * We need this because findClass is protected in URLClassLoader | |
36 | + */ | |
37 | + private static class ChildURLClassLoader extends URLClassLoader | |
38 | + { | |
39 | + private FindClassClassLoader realParent; | |
40 | + | |
41 | + public ChildURLClassLoader(URL[] urls, FindClassClassLoader realParent ) | |
42 | + { | |
43 | + super(urls, null); | |
44 | + | |
45 | + this.realParent = realParent; | |
46 | + } | |
47 | + | |
48 | + @Override | |
49 | + public Class<?> findClass(String name) throws ClassNotFoundException | |
50 | + { | |
51 | + try | |
52 | + { | |
53 | + // first try to use the URLClassLoader findClass | |
54 | + return super.findClass(name); | |
55 | + } | |
56 | + catch( ClassNotFoundException e ) | |
57 | + { | |
58 | + // if that fails, we ask our real parent classloader to load the class (we give up) | |
59 | + return realParent.loadClass(name); | |
60 | + } | |
61 | + } | |
62 | + } | |
63 | + | |
64 | + //List<URL> classpath | |
65 | + public ParentLastURLClassLoader(URL[] urls) | |
66 | + { | |
67 | + super(Thread.currentThread().getContextClassLoader()); | |
68 | + | |
69 | + //URL[] urls = classpath.toArray(new URL[classpath.size()]); | |
70 | + | |
71 | + childClassLoader = new ChildURLClassLoader( urls, new FindClassClassLoader(this.getParent()) ); | |
72 | + } | |
73 | + | |
74 | + @Override | |
75 | + protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException | |
76 | + { | |
77 | + try | |
78 | + { | |
79 | + // first we try to find a class inside the child classloader | |
80 | + return childClassLoader.findClass(name); | |
81 | + } | |
82 | + catch( ClassNotFoundException e ) | |
83 | + { | |
84 | + // didn't find it, try the parent | |
85 | + return super.loadClass(name, resolve); | |
86 | + } | |
87 | + } | |
88 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/util/reflection/ReflectionUtil.java
... | ... | @@ -0,0 +1,220 @@ |
1 | +package com.takensoft.taken_bi_manager.common.util.reflection; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
4 | +import com.takensoft.taken_bi_manager.common.util.bean.BeanUtil; | |
5 | + | |
6 | +import java.io.File; | |
7 | +import java.lang.reflect.Method; | |
8 | +import java.net.URL; | |
9 | + | |
10 | +/** | |
11 | + * @author 최정우 | |
12 | + * @since 2020.11.25 | |
13 | + * | |
14 | + * Reflection - 클래스, 인터페이스, 메소드관련 인스턴스화(로드) 및 실행 관련 Util입니다. | |
15 | + */ | |
16 | +public class ReflectionUtil { | |
17 | + | |
18 | + /******************************************** Class 단 ********************************************/ | |
19 | + /** | |
20 | + * @author 최정우 | |
21 | + * @since 2020.11.25 | |
22 | + * | |
23 | + * classLoad - 어플리케이션 내부(+Bean객체포함) OR 외부의 class 파일을 저장된 경로를 통해 class 파일 로드 후, 객체 생성 | |
24 | + * | |
25 | + * classFullName과 classFilePath를 통해 실제 클래스를 인스턴스화함. | |
26 | + * 1. Class.forName을 통해 어플리케이션 내부의 class path에 있는 class객체 생성 | |
27 | + * 2. 어플리케이션 내부에 class가 존재할 때 | |
28 | + * 2-1. 어플리케이션의 Spring 컨테이너에 해당 클래스 타입으로 생성된 Bean이 있는지 확인 | |
29 | + * => 존재할 때, Bean 객체 주입 | |
30 | + * => 존재하지 않을 때, 객체 생성 | |
31 | + * 3. 어플리케이션 내부에 class가 존재하지 않을 때 | |
32 | + * 3-1. class or jar file이 저장된 경로를 이용하여 클래스를 로드 | |
33 | + * | |
34 | + * 4. 객체 생성 실패시, Log 기록 및 다음 작업 목록으로 넘어감 | |
35 | + */ | |
36 | + public static Object classAndBeanLoad (String classFilePath, String classFullName) { | |
37 | + Object clazz = null; | |
38 | + try { | |
39 | + //Class.forName을 통해 어플리케이션 내부의 class path에 있는 class객체 생성 | |
40 | + Class<?> c = forName(classFullName); | |
41 | + if (c != null) {//어플리케이션 내부에 class가 존재할 때 | |
42 | + //플리케이션의 Spring 컨테이너에 해당 클래스 타입으로 생성된 Bean이 있는지 확인 후, Bean 객체 주입 | |
43 | + clazz = BeanUtil.getBean(c); | |
44 | + | |
45 | + if (clazz == null) {//Bean 객체 존재하지 않을 때 | |
46 | + clazz = newInstance(c); | |
47 | + } | |
48 | + } else {//어플리케이션 내부에 class가 존재하지 않을 때 | |
49 | + //class or jar file이 저장된 경로 | |
50 | + //file 경로 값이 있을 때만 클래스를 로드함 | |
51 | + if (StringUtil.isEmpty(classFilePath) == false) { | |
52 | + if (StringUtil.isEmpty(classFullName) == false) { | |
53 | + clazz = classLoad(classFilePath, classFullName); | |
54 | + } else { | |
55 | + clazz = classLoad(classFilePath); | |
56 | + } | |
57 | + } | |
58 | + } | |
59 | + } catch (Exception e) { | |
60 | + e.printStackTrace(); | |
61 | + } | |
62 | + | |
63 | + return clazz; | |
64 | + } | |
65 | + | |
66 | + /** | |
67 | + * @author 최정우 | |
68 | + * @since 2019.11.17 | |
69 | + * | |
70 | + * forName - 어플리케이션 내부의 class path에 있는 class객체 생성 | |
71 | + * | |
72 | + * classFullName = package명 + class명 | |
73 | + */ | |
74 | + public static Class<?> forName (String classFullName) { | |
75 | + try { | |
76 | + return Class.forName(classFullName); | |
77 | + } catch (Exception e) { | |
78 | + e.printStackTrace(); | |
79 | + return null; | |
80 | + } | |
81 | + } | |
82 | + | |
83 | + /** | |
84 | + * @author 최정우 | |
85 | + * @since 2019.11.17 | |
86 | + * | |
87 | + * classLoad - 어플리케이션 내부 OR 외부의 class 파일을 저장된 경로를 통해 class 파일 로드 후, 객체 생성 | |
88 | + * 주로 외부 class파일을 로드할 때 쓰임 | |
89 | + * | |
90 | + * classFilePath - 클래스파일 절대경로 | |
91 | + * classFullName = package명 + class명 | |
92 | + */ | |
93 | + public static Object classLoad (String classFilePath, String classFullName) { | |
94 | + try { | |
95 | + File file = new File(classFilePath); | |
96 | + //실제 경로상에 있는 .class파일을 통해 class를 읽어옴 | |
97 | + ParentLastURLClassLoader classLoader = new ParentLastURLClassLoader(new URL[] { file.toURI().toURL() }); | |
98 | + //읽어온 .class파일을 이용해 해당되는 패키지 내에 있는 class를 로드해 옴 | |
99 | + Class<?> c = classLoader.loadClass(classFullName); | |
100 | + //class를 new 객체 생성함 | |
101 | + return newInstance(c); | |
102 | + } catch (Exception e) { | |
103 | + e.printStackTrace(); | |
104 | + return null; | |
105 | + } | |
106 | + } | |
107 | + | |
108 | + /** | |
109 | + * @author 최정우 | |
110 | + * @since 2019.11.17 | |
111 | + * | |
112 | + * classLoad - 어플리케이션 내부 OR 외부의 class 파일을 저장된 경로를 통해 class 파일 로드 후, 객체 생성 | |
113 | + * 주로 외부 class파일을 로드할 때 쓰임 | |
114 | + * class명을 모를 때 사용 | |
115 | + * | |
116 | + * classFilePath - 클래스파일 절대경로 | |
117 | + */ | |
118 | + public static Object classLoad (String classFilePath) { | |
119 | + try { | |
120 | + File file = new File(classFilePath); | |
121 | + //실제 경로상에 있는 .class파일을 통해 class를 읽어옴 | |
122 | + ParentLastURLClassLoader classLoader = new ParentLastURLClassLoader(new URL[] { file.toURI().toURL() }); | |
123 | + //읽어온 .class파일을 이용해 해당되는 패키지 내에 있는 class를 로드해 옴 | |
124 | + Class<?> c = classLoader.getClass(); | |
125 | + //class를 new 객체 생성함 | |
126 | + return newInstance(c); | |
127 | + } catch (Exception e) { | |
128 | + e.printStackTrace(); | |
129 | + return null; | |
130 | + } | |
131 | + } | |
132 | + | |
133 | + /** | |
134 | + * @author 최정우 | |
135 | + * @since 2019.11.17 | |
136 | + * | |
137 | + * newInstance - 객체 인스턴스화(로드) | |
138 | + */ | |
139 | + public static Object newInstance(Class<?> c) { | |
140 | + try { | |
141 | + return c.newInstance(); | |
142 | + } catch (Exception e) { | |
143 | + e.printStackTrace(); | |
144 | + return null; | |
145 | + } | |
146 | + } | |
147 | + | |
148 | + /******************************************** Class 단 ********************************************/ | |
149 | + | |
150 | + | |
151 | + | |
152 | + /******************************************** Method 단 ********************************************/ | |
153 | + /** | |
154 | + * @author 최정우 | |
155 | + * @since 2019.11.17 | |
156 | + * | |
157 | + * invokeByMethodName - 메소드 이름을 통한 메소드 호출 | |
158 | + * | |
159 | + * clazz - 인스턴스화(로드)된 객체 | |
160 | + * methodName - 메소드명 | |
161 | + * paramValues - 메소드의 파라메터 값 | |
162 | + * paramTypes - 메소드의 파라메터 타입 | |
163 | + * (주의 paramValues, paramTypes 순서가 같아야함) | |
164 | + */ | |
165 | + public static Object invokeByMethodName (Object clazz, String methodName, Object[] paramValues, Class<?>[] paramTypes) throws Exception { | |
166 | + try { | |
167 | + Method method = null; | |
168 | + if (paramValues != null && paramTypes != null | |
169 | + && paramValues.length > 0 && paramTypes.length > 0 | |
170 | + && paramValues.length == paramTypes.length) { | |
171 | + | |
172 | + | |
173 | + if (paramValues != null && paramValues.length > 0) { | |
174 | + | |
175 | + } | |
176 | + | |
177 | + //메소드 객체 가지고오기 | |
178 | + method = clazz.getClass().getMethod(methodName, paramTypes); | |
179 | + } else { | |
180 | + //메소드 객체 가지고오기 | |
181 | + method = clazz.getClass().getMethod(methodName); | |
182 | + } | |
183 | + | |
184 | + //메소드 호출 | |
185 | + return invoke(clazz, method, paramValues); | |
186 | + | |
187 | + } catch (Exception e) { | |
188 | + e.printStackTrace(); | |
189 | + throw new Exception(e); | |
190 | + } | |
191 | + | |
192 | + } | |
193 | + | |
194 | + /** | |
195 | + * @author 최정우 | |
196 | + * @since 2019.11.17 | |
197 | + * | |
198 | + * invoke - 메소드 호출 | |
199 | + * | |
200 | + * clazz - 인스턴스화(로드)된 객체 | |
201 | + * method - 메소드 객체 | |
202 | + * paramValues - 메소드의 파라메터 값 | |
203 | + */ | |
204 | + public static Object invoke (Object clazz, Method method, Object[] paramValues) throws Exception { | |
205 | + try { | |
206 | + if (paramValues != null && paramValues.length > 0) { | |
207 | + //메소드 호출 | |
208 | + return method.invoke(clazz, paramValues); | |
209 | + } else { | |
210 | + //메소드 호출 | |
211 | + return method.invoke(clazz); | |
212 | + } | |
213 | + } catch (Exception e) { | |
214 | + e.printStackTrace(); | |
215 | + throw new Exception(e); | |
216 | + } | |
217 | + | |
218 | + } | |
219 | + /******************************************** Method 단 ********************************************/ | |
220 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/CheckMessage.java
... | ... | @@ -0,0 +1,81 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +/** | |
7 | + * @author 김성원 | |
8 | + * @since 2024.01.04 | |
9 | + * | |
10 | + * 데이터 체크, 유효성 검사 등과 같이 검사와 관련된 변수를 정의한 Class 입니다. | |
11 | + */ | |
12 | +@Getter | |
13 | +@Setter | |
14 | +public class CheckMessage { | |
15 | + | |
16 | + public CheckMessage() {} | |
17 | + | |
18 | + public CheckMessage(boolean isSuccess) { | |
19 | + this.isSuccess = isSuccess; | |
20 | + } | |
21 | + | |
22 | + public CheckMessage(String message) { | |
23 | + this.message = message; | |
24 | + } | |
25 | + | |
26 | + public CheckMessage(boolean isSuccess, String message) { | |
27 | + this.isSuccess = isSuccess; | |
28 | + this.message = message; | |
29 | + } | |
30 | + | |
31 | + public CheckMessage(boolean isSuccess, String message, int status) { | |
32 | + this.isSuccess = isSuccess; | |
33 | + this.message = message; | |
34 | + this.status = status; | |
35 | + } | |
36 | + | |
37 | + public CheckMessage(boolean isSuccess, String message, String error) { | |
38 | + this.isSuccess = isSuccess; | |
39 | + this.message = message; | |
40 | + this.error = error; | |
41 | + } | |
42 | + | |
43 | + /** | |
44 | + * 체크 완료(사용가능 or 성공) 여부 | |
45 | + */ | |
46 | + private boolean isSuccess; | |
47 | + | |
48 | + /** | |
49 | + * 체크한 상태의 메세지값 | |
50 | + */ | |
51 | + private String message; | |
52 | + | |
53 | + /** | |
54 | + * 에러 메세지 | |
55 | + */ | |
56 | + private String error; | |
57 | + | |
58 | + /** | |
59 | + * 체크한 상태의 상태값 -> 상황마다 다름 | |
60 | + */ | |
61 | + private int status; | |
62 | + | |
63 | + | |
64 | + // 오류처리 | |
65 | + public void setError(String message) { | |
66 | + this.message = message; | |
67 | + this.error = message; | |
68 | + this.isSuccess = false; | |
69 | + this.status = 0; | |
70 | + } | |
71 | + | |
72 | + // 오류처리(에러코드 추가) | |
73 | + public void setError(String message, int errorCode) { | |
74 | + this.message = message; | |
75 | + this.error = message; | |
76 | + this.isSuccess = false; | |
77 | + this.status = errorCode; | |
78 | + } | |
79 | + | |
80 | + | |
81 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/CommonVO.java
... | ... | @@ -0,0 +1,139 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import java.sql.Timestamp; | |
4 | +import java.util.ArrayList; | |
5 | +import java.util.List; | |
6 | + | |
7 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
8 | + | |
9 | +import lombok.Getter; | |
10 | +import lombok.Setter; | |
11 | + | |
12 | + | |
13 | + | |
14 | +/** | |
15 | + * @author 김성원 | |
16 | + * @since 2024.01.09 | |
17 | + * | |
18 | + * 공통 검색 VO 입니다.(상속받으세요) | |
19 | + */ | |
20 | +@Getter | |
21 | +@Setter | |
22 | +public class CommonVO { | |
23 | + | |
24 | + /**************************** 공통 ****************************/ | |
25 | + /** | |
26 | + * 검색조건 | |
27 | + */ | |
28 | + private String searchCondition = ""; | |
29 | + | |
30 | + /** | |
31 | + * 검색Keyword | |
32 | + */ | |
33 | + private String searchKeyword = ""; | |
34 | + | |
35 | + /** | |
36 | + * 검색Keyword | |
37 | + */ | |
38 | + private List<String> searchKeywordList = new ArrayList<String>(); | |
39 | + | |
40 | + /** | |
41 | + * 검색사용여부 | |
42 | + */ | |
43 | + private String searchUseYn = ""; | |
44 | + | |
45 | + /** | |
46 | + * 검색 시작일 | |
47 | + */ | |
48 | + private String startDate = ""; | |
49 | + | |
50 | + /** | |
51 | + * 검색 종료일 | |
52 | + */ | |
53 | + private String endDate = ""; | |
54 | + | |
55 | + /** | |
56 | + * 정렬 기준 (컬럼명) | |
57 | + */ | |
58 | + private String order = ""; | |
59 | + | |
60 | + /** | |
61 | + * 정렬 타입 | |
62 | + * true - ASC | |
63 | + * false - DESC | |
64 | + */ | |
65 | + private boolean isOrderASC = true; | |
66 | + | |
67 | + /** | |
68 | + * 현재페이지 | |
69 | + */ | |
70 | + private int currentPage = 1; | |
71 | + | |
72 | + /** | |
73 | + * 페이지갯수 | |
74 | + */ | |
75 | + private int perPage = 10; | |
76 | + | |
77 | + /** | |
78 | + * 총 개시물 수 | |
79 | + */ | |
80 | + private int totalRows; | |
81 | + | |
82 | + /** | |
83 | + * 페이징 사용 유무 | |
84 | + */ | |
85 | + private boolean isUsePaging = true; | |
86 | + | |
87 | + /** firstIndex */ | |
88 | + private int firstIndex = 1; | |
89 | + | |
90 | + /** lastIndex */ | |
91 | + private int lastIndex = 1; | |
92 | + | |
93 | + /** 페이지사이즈 */ | |
94 | + private int pageSize = 10; | |
95 | + | |
96 | + /** recordCountPerPage */ | |
97 | + private int recordCountPerPage = 10; | |
98 | + | |
99 | + | |
100 | + public boolean getIsUsePaging() { | |
101 | + return isUsePaging; | |
102 | + } | |
103 | + | |
104 | + public void setIsUsePaging(boolean isUsePaging) { | |
105 | + this.isUsePaging = isUsePaging; | |
106 | + } | |
107 | + /**************************** 공통 ****************************/ | |
108 | + | |
109 | + /**************************** 검색어 분할 ****************************/ | |
110 | + | |
111 | + | |
112 | + public void setSearchKeywordList(List<String> searchKeywordList) { | |
113 | + this.searchKeywordList = searchKeywordList; | |
114 | + } | |
115 | + /**************************** 검색어 분할 ****************************/ | |
116 | + | |
117 | + /**************************** 데이터베이스 별 페이징 ****************************/ | |
118 | + | |
119 | + | |
120 | + private int startIndex; | |
121 | + | |
122 | + /** | |
123 | + * 마지막 게시물의 인덱스 번호 (변환과정없음, 0부터 시작) | |
124 | + */ | |
125 | + private long limit = 0; | |
126 | + | |
127 | + | |
128 | + public void searchClear() { | |
129 | + searchCondition = ""; | |
130 | + searchKeyword = ""; | |
131 | + searchUseYn = ""; | |
132 | + startDate = ""; | |
133 | + endDate = ""; | |
134 | + order = ""; | |
135 | + } | |
136 | + | |
137 | + /**************************** 데이터베이스 별 페이징 ****************************/ | |
138 | + | |
139 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/CustomeResultMap.java
... | ... | @@ -0,0 +1,28 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +import java.util.HashMap; | |
7 | + | |
8 | +/** | |
9 | + * 컨트롤러의 데이터를 반환할 기본 Map클래스 | |
10 | + * | |
11 | + * @author 김성원 | |
12 | + * @since 2023.12.28 | |
13 | + */ | |
14 | +@Getter | |
15 | +@Setter | |
16 | +public class CustomeResultMap { | |
17 | + | |
18 | + // 결과메세지 | |
19 | + private CheckMessage checkMessage; | |
20 | + | |
21 | + // 결과 데이터 | |
22 | + private HashMap<String,Object> resultData = new HashMap<String,Object>(); | |
23 | + | |
24 | + public CustomeResultMap(){ | |
25 | + checkMessage = new CheckMessage(true, "성공" , 200); | |
26 | + } | |
27 | + | |
28 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/EditVo.java
... | ... | @@ -0,0 +1,28 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +/** | |
7 | + * @author 김성원 | |
8 | + * @since 2022.01.18 | |
9 | + * | |
10 | + * 에디트 관련 상속 테이블 입니다. | |
11 | + */ | |
12 | + | |
13 | +@Getter | |
14 | +@Setter | |
15 | +public class EditVo { | |
16 | + | |
17 | + // 현재 스탯 1 = 기본 2 = 에디트 3 = 삭제 | |
18 | + private int status = 1; | |
19 | + | |
20 | + | |
21 | + // 에디트 가능여브 | |
22 | + private boolean enableEdit = false; | |
23 | + | |
24 | + // 변경데이터 | |
25 | + private Object orgData; | |
26 | + | |
27 | + | |
28 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/PopupManage.java
... | ... | @@ -0,0 +1,18 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +/** | |
7 | + * @author 김성원 | |
8 | + * @since 2024.03.22 | |
9 | + * | |
10 | + * 팝업관리 VO 객체 | |
11 | + */ | |
12 | +@Getter | |
13 | +@Setter | |
14 | +public class PopupManage { | |
15 | + | |
16 | + // 팝업 오픈관리 | |
17 | + private boolean opener; | |
18 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/SearchObject.java
... | ... | @@ -0,0 +1,44 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +/** | |
7 | + * @author 김성원 | |
8 | + * @since 2024.01.09 | |
9 | + * | |
10 | + * 공통 검색용 VO 입니다 | |
11 | + */ | |
12 | +@Getter | |
13 | +@Setter | |
14 | +public class SearchObject { | |
15 | + | |
16 | + /** | |
17 | + * 검색 key | |
18 | + */ | |
19 | + private String key; | |
20 | + | |
21 | + /** | |
22 | + * 검색 값 | |
23 | + */ | |
24 | + private Object value; | |
25 | + | |
26 | + | |
27 | + /** | |
28 | + * 검색 key | |
29 | + */ | |
30 | + private String key2; | |
31 | + | |
32 | + /** | |
33 | + * 검색 값 | |
34 | + */ | |
35 | + private Object value2; | |
36 | + | |
37 | + | |
38 | + /** | |
39 | + * 데이터 타입(날짜 : date, 숫자 : int, 문자 : string, 체크 : bool, 날짜쌍 : dates) | |
40 | + */ | |
41 | + private String type; | |
42 | + | |
43 | + | |
44 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/SearchVO.java
... | ... | @@ -0,0 +1,73 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import lombok.Getter; | |
4 | +import lombok.Setter; | |
5 | + | |
6 | +import java.util.*; | |
7 | + | |
8 | +/** | |
9 | + * @author 김성원 | |
10 | + * @since 2024.01.09 | |
11 | + * | |
12 | + * 공통 검색 VO 입니다 | |
13 | + */ | |
14 | +@Getter | |
15 | +@Setter | |
16 | +public class SearchVO { | |
17 | + /** | |
18 | + * 검색Keyword | |
19 | + */ | |
20 | + private List<SearchObject> searchObjectList = new ArrayList<SearchObject>(); | |
21 | + | |
22 | + /** | |
23 | + * 정렬 기준 (컬럼명) | |
24 | + */ | |
25 | + private String order = ""; | |
26 | + | |
27 | + /** | |
28 | + * 정렬 타입 | |
29 | + * true - ASC | |
30 | + * false - DESC | |
31 | + */ | |
32 | + private boolean orderASC = true; | |
33 | + | |
34 | + /** | |
35 | + * 현재페이지 | |
36 | + */ | |
37 | + private int currentPage = 1; | |
38 | + | |
39 | + /** | |
40 | + * 페이지갯수 | |
41 | + */ | |
42 | + private int perPage = 10; | |
43 | + | |
44 | + /** | |
45 | + * 총 개시물 수 | |
46 | + */ | |
47 | + private int totalRows; | |
48 | + | |
49 | + /** | |
50 | + * 검색 key | |
51 | + */ | |
52 | + private String searchText; | |
53 | + | |
54 | + /** | |
55 | + * 검색 값 | |
56 | + */ | |
57 | + private Object value; | |
58 | + | |
59 | + /** | |
60 | + * 검색 key | |
61 | + */ | |
62 | + private String key2; | |
63 | + | |
64 | + /** | |
65 | + * 검색 값 | |
66 | + */ | |
67 | + private Object value2; | |
68 | + | |
69 | + /** | |
70 | + * 데이터 타입(날짜 : date, 숫자 : int, 문자 : string, 체크 : bool, 날짜쌍 : dates) | |
71 | + */ | |
72 | + private String type; | |
73 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/common/vo/SystemCode.java
... | ... | @@ -0,0 +1,579 @@ |
1 | +package com.takensoft.taken_bi_manager.common.vo; | |
2 | + | |
3 | +import java.math.BigDecimal; | |
4 | +import java.sql.Timestamp; | |
5 | +import java.util.ArrayList; | |
6 | +import java.util.Arrays; | |
7 | +import java.util.Date; | |
8 | +import java.util.HashMap; | |
9 | +import java.util.LinkedHashMap; | |
10 | +import java.util.List; | |
11 | +import java.util.Map; | |
12 | +import java.util.regex.Pattern; | |
13 | + | |
14 | +import com.sun.jna.platform.win32.Sspi.TimeStamp; | |
15 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
16 | +import com.takensoft.taken_bi_manager.common.util.CommonUtil; | |
17 | +import com.takensoft.taken_bi_manager.common.util.StringUtil; | |
18 | + | |
19 | + | |
20 | + | |
21 | + | |
22 | +public class SystemCode { | |
23 | + | |
24 | + //191자 => mariaDB에서 indexing가능한 최대 크기 765Byte/한글 4Byte(utf8mb4) | |
25 | + public final static int DEFAULT_VARCHAR_SIZE = 191; | |
26 | + | |
27 | + //mariaDB에서 indexing가능한 varchar 최대 크기 765Byte | |
28 | + public final static int MAX_VARCHAR_SIZE = 765; | |
29 | + | |
30 | + | |
31 | + /** | |
32 | + * @author 최정우 | |
33 | + * @since 2019.11.13 | |
34 | + * | |
35 | + * 데이터 타입을 정의한 상수 Class 입니다. | |
36 | + * 상수명(java데이터타입, 초기값, mysql데이터타입, display데이터타입 | |
37 | + */ | |
38 | + public enum DataType { | |
39 | + NULL(null, null) | |
40 | + , BYTE(Byte.class, 0) | |
41 | + , BOOL(Boolean.class, false) | |
42 | + , CHAR(Character.class, '\u0000') | |
43 | + , STRING(String.class, "") | |
44 | + , SHORT(Short.class, 0) | |
45 | + , INT(Integer.class, 0) | |
46 | + , DECIMAL(BigDecimal.class,0) | |
47 | + , LONG(Long.class, 0) | |
48 | + , FLOAT(Float.class, 0.0) | |
49 | + , DOUBLE(Double.class, 0.0) | |
50 | + , DATE(Date.class, "") | |
51 | + , DATETIME(Date.class, "") | |
52 | + , TIMESTAMP(Timestamp.class, "") | |
53 | + , ENTER(Character.class,'\n'); | |
54 | + | |
55 | + /** | |
56 | + * enum(열거형데이터)의 생성자 | |
57 | + * 1. 상수에 나열된 parameter와 형태가 똑같이 만들어줘야함. | |
58 | + * 2. 접근제한자는 private로만 다른 접근제한자는 허용하지 않음 | |
59 | + */ | |
60 | + private DataType (Class<?> javaType, Object iniValue) { | |
61 | + this.javaType = javaType; | |
62 | + this.initValue = iniValue; | |
63 | + } | |
64 | + | |
65 | + /** | |
66 | + * java데이터타입 | |
67 | + */ | |
68 | + final private Class<?> javaType; | |
69 | + | |
70 | + /** | |
71 | + * 초기값 | |
72 | + */ | |
73 | + final private Object initValue; | |
74 | + | |
75 | + public Class<?> getJavaType() { | |
76 | + return javaType; | |
77 | + } | |
78 | + public Object getInitValue() { | |
79 | + return initValue; | |
80 | + } | |
81 | + | |
82 | + | |
83 | + /** | |
84 | + * 데이터 타입 검사, DataType 조회 | |
85 | + */ | |
86 | + public static Map<DataType, String> getDataTypeList () { | |
87 | + Map<DataType, String> info = new LinkedHashMap<DataType, String>(); | |
88 | + info.put(STRING, "문자열"); | |
89 | + info.put(LONG, "정수"); | |
90 | + info.put(DOUBLE, "실수"); | |
91 | + info.put(DATE, "날짜"); | |
92 | + info.put(DATETIME,"날짜,시간"); | |
93 | + return info; | |
94 | + } | |
95 | + | |
96 | + | |
97 | + /** | |
98 | + * 데이터 타입 검사, DataType 조회 | |
99 | + */ | |
100 | + public static List<DataType> getDataTypeArray () { | |
101 | + List<DataType> info = new ArrayList<DataType>(); | |
102 | + info.add(STRING); | |
103 | + info.add(LONG); | |
104 | + info.add(DOUBLE); | |
105 | + info.add(DATE); | |
106 | + info.add(DATETIME); | |
107 | + info.add(BOOL); | |
108 | + return info; | |
109 | + } | |
110 | + | |
111 | + /** | |
112 | + * 데이터 타입 검사, DataType 조회 | |
113 | + */ | |
114 | + public static DataType getDataType (String text) { | |
115 | + /* | |
116 | + * 2021-11-02 김혜민 dataType 전화번호, 날짜 정규식 수정 | |
117 | + * | |
118 | + * | |
119 | + * 전화번호 정규식*/ | |
120 | + String regExp = "^\\d{2,3}-\\d{3,4}-\\d{4}$"; | |
121 | + String regDateTime = "\\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]) (0[1-9]|1[0-9]|2[0-4]):(0[1-9]|[1-5][0-9]):(0[1-9]|[1-5][0-9])"; | |
122 | + String regDate = "\\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])"; | |
123 | + | |
124 | + if(StringUtil.isEmpty(text)) { | |
125 | + return NULL; | |
126 | + } else if(CommonUtil.isLong(text)) { | |
127 | + /* | |
128 | + * 숫자로 변환 가능 하지만 앞에 '0'이 붙어 있으면 문자열로 봄 | |
129 | + * ex) 0102 -> String, 1102 -> Long | |
130 | + */ | |
131 | + if (text.length() > 1 && text.indexOf("0") == 0) { | |
132 | + return STRING; | |
133 | + } else { | |
134 | + return LONG; | |
135 | + } | |
136 | + }else if(CommonUtil.isDouble(text)) { | |
137 | + | |
138 | + return DOUBLE; | |
139 | + | |
140 | + } else if (CommonUtil.isDate(text)) { | |
141 | + /* | |
142 | + * 2021-11-02 김혜민 dataType 전화번호, 날짜 정규식 수정 | |
143 | + * | |
144 | + * | |
145 | + * 전화번호 정규식*/ | |
146 | + boolean expResult = Pattern.matches(regExp, text); | |
147 | + boolean dateTimeResult = Pattern.matches(regDateTime, text); | |
148 | + boolean dateResult = Pattern.matches(regDate, text); | |
149 | + | |
150 | + if(expResult) { | |
151 | + return STRING; | |
152 | + }else if(dateResult) { | |
153 | + return DATE; | |
154 | + }else { | |
155 | + return DATETIME; | |
156 | + } | |
157 | + | |
158 | + } else { | |
159 | + return STRING; | |
160 | + } | |
161 | + } | |
162 | + | |
163 | + /** | |
164 | + * 데이터 타입 검사, dbDataType 조회 | |
165 | + */ | |
166 | + public static String convertDbDataType (DataType datatype, Integer size) { | |
167 | + if (datatype == STRING) { | |
168 | + if (size == null || size <= MAX_VARCHAR_SIZE) { | |
169 | + return "varchar"; | |
170 | + } else { | |
171 | + return "text"; | |
172 | + } | |
173 | + } else if (datatype == DATE) { | |
174 | + return "date"; | |
175 | + } else if (datatype == DATETIME){ | |
176 | + return "datetime"; | |
177 | + } else if (datatype == LONG) { | |
178 | + return "bigint"; | |
179 | + } else if (datatype == DOUBLE) { | |
180 | + return "double"; | |
181 | + } else { | |
182 | + return "varchar"; | |
183 | + } | |
184 | + } | |
185 | + | |
186 | + /** | |
187 | + * 데이터 타입 검사, dbDataType -> javaType 조회 | |
188 | + */ | |
189 | + public static DataType convertDataTypeDbtoJava (DataType datatype, Integer size) { | |
190 | + | |
191 | + | |
192 | + return null; | |
193 | + } | |
194 | + | |
195 | + | |
196 | + /** | |
197 | + * 데이터 타입 형태로 값 변경 | |
198 | + */ | |
199 | + public static Object parse(DataType dataType, Object value) { | |
200 | + if (CommonUtil.isNull(value) == true) { | |
201 | + return null; | |
202 | + } | |
203 | + | |
204 | + Class<?> javaType = dataType.getJavaType(); | |
205 | + try { | |
206 | + if (javaType.getSimpleName().equals("Byte")) { | |
207 | + return Byte.parseByte(value.toString()); | |
208 | + } else if (javaType.getSimpleName().equals("Boolean")) { | |
209 | + return Boolean.parseBoolean(value.toString()); | |
210 | + } else if (javaType.getSimpleName().equals("Character")) { | |
211 | + return value.toString().toCharArray(); | |
212 | + } else if (javaType.getSimpleName().equals("String")) { | |
213 | + return value.toString(); | |
214 | + } else if (javaType.getSimpleName().equals("Short")) { | |
215 | + //Short.parseShort(value.toString().replaceAll("[^0-9]","")); | |
216 | + return Short.parseShort(value.toString()); | |
217 | + } else if (javaType.getSimpleName().equals("Integer")) { | |
218 | + //Integer.parseInt(value.toString().replaceAll("[^0-9]","")); | |
219 | + return Integer.parseInt(value.toString()); | |
220 | + } else if (javaType.getSimpleName().equals("Long")) { | |
221 | + //Long.parseLong(value.toString().replaceAll("[^0-9]","")); | |
222 | + return Long.parseLong(value.toString()); | |
223 | + } else if (javaType.getSimpleName().equals("Float")) { | |
224 | + //Float.parseFloat(value.toString().replaceAll("[^0-9]","")); | |
225 | + return Float.parseFloat(value.toString()); | |
226 | + } else if (javaType.getSimpleName().equals("Double")) { | |
227 | + //Double.parseDouble(value.toString().replaceAll("[^0-9]","")); | |
228 | + return Double.parseDouble(value.toString()); | |
229 | + } else { | |
230 | + return value; | |
231 | + } | |
232 | + } catch (Exception e) { | |
233 | + e.printStackTrace(); | |
234 | + return dataType.getInitValue(); | |
235 | + } | |
236 | + } | |
237 | + | |
238 | + /** | |
239 | + * 데이터 타입 형태로 값 변경 | |
240 | + */ | |
241 | + public static boolean parseCheck (DataType dataType, Object value) { | |
242 | + if (CommonUtil.isNull(value) == true) { | |
243 | + return false; | |
244 | + } | |
245 | + | |
246 | + Class<?> javaType = dataType.getJavaType(); | |
247 | + try { | |
248 | + if (javaType.getSimpleName().equals("Byte")) { | |
249 | + Byte.parseByte(value.toString()); | |
250 | + } else if (javaType.getSimpleName().equals("Boolean")) { | |
251 | + Boolean.parseBoolean(value.toString()); | |
252 | + } else if (javaType.getSimpleName().equals("Character")) { | |
253 | + value.toString().toCharArray(); | |
254 | + } else if (javaType.getSimpleName().equals("String")) { | |
255 | + value.toString(); | |
256 | + } else if (javaType.getSimpleName().equals("Short")) { | |
257 | + //Short.parseShort(value.toString().replaceAll("[^0-9]","")); | |
258 | + Short.parseShort(value.toString()); | |
259 | + } else if (javaType.getSimpleName().equals("Integer")) { | |
260 | + //Integer.parseInt(value.toString().replaceAll("[^0-9]","")); | |
261 | + Integer.parseInt(value.toString()); | |
262 | + } else if (javaType.getSimpleName().equals("Long")) { | |
263 | + //Long.parseLong(value.toString().replaceAll("[^0-9]","")); | |
264 | + Long.parseLong(value.toString()); | |
265 | + } else if (javaType.getSimpleName().equals("Float")) { | |
266 | + //Float.parseFloat(value.toString().replaceAll("[^0-9]","")); | |
267 | + Float.parseFloat(value.toString()); | |
268 | + } else if (javaType.getSimpleName().equals("Double")) { | |
269 | + //Double.parseDouble(value.toString().replaceAll("[^0-9]","")); | |
270 | + Double.parseDouble(value.toString()); | |
271 | + } | |
272 | + | |
273 | + return true; | |
274 | + } catch (Exception e) { | |
275 | + //e.printStackTrace(); | |
276 | + return false; | |
277 | + } | |
278 | + } | |
279 | + | |
280 | + } | |
281 | + | |
282 | + /** | |
283 | + * @author 최정우 | |
284 | + * @since 2019.12.03 | |
285 | + * | |
286 | + * 데이터 셋의 타입을 정의한 상수 Class 입니다. | |
287 | + */ | |
288 | + public enum DatasetType { | |
289 | + RAW("raw_") | |
290 | + , TRANSFORM("transform_"); | |
291 | + | |
292 | + DatasetType(String prefix) { | |
293 | + this.prefix = prefix; | |
294 | + } | |
295 | + | |
296 | + /** | |
297 | + * prefix | |
298 | + */ | |
299 | + final String prefix; | |
300 | + | |
301 | + /** | |
302 | + * prefix 조회 | |
303 | + */ | |
304 | + public String getPrefix () { | |
305 | + return prefix; | |
306 | + } | |
307 | + | |
308 | + /** | |
309 | + * 데이터 셋의 타입 목록 조회 | |
310 | + */ | |
311 | + public static Map<DatasetType, String> getDatasetTypeList () { | |
312 | + Map<DatasetType, String> info = new LinkedHashMap<DatasetType, String>(); | |
313 | + DatasetType[] array = DatasetType.values(); | |
314 | + for (int i = 0; i < array.length; i++) { | |
315 | + info.put(array[i], array[i].getPrefix()); | |
316 | + } | |
317 | + return info; | |
318 | + } | |
319 | + } | |
320 | + | |
321 | + /** | |
322 | + * @author 최정우 | |
323 | + * @since 2019.11.20 | |
324 | + * | |
325 | + * 데이터 베이스 타입별 상수를 정의 | |
326 | + */ | |
327 | + public enum DatabaseType { | |
328 | + MYSQL("MySql", "com.mysql.jdbc.Driver", "jdbc:mysql://", "3306", "allowMultiQueries=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC") | |
329 | + , MARIADB("MariaDB", "org.mariadb.jdbc.Driver", "jdbc:mariadb://", "3306", "") | |
330 | + , ORACLE("Oracle", "oracle.jdbc.OracleDriver", "jdbc:oracle:thin:@", "1521", "useUnicode=true&characterEncoding=UTF-8") | |
331 | + , MSSQL("MS-SQL", "com.microsoft.sqlserver.jdbc.SQLServerDriver", "jdbc:sqlserver://", "1433", "trustServerCertificate=true") | |
332 | + , TIBERO("Tibero", "com.tmax.tibero.jdbc.TbDriver", "jdbc:tibero:thin:@", "8629", "") | |
333 | + , POSTGRESQL("PostgreSql", "org.postgresql.Driver", "jdbc:postgresql://", "5432", ""); | |
334 | + | |
335 | + private DatabaseType(String value, String driverClassName, String baseUrl, String defalutPort, String option) { | |
336 | + this.value = value; | |
337 | + this.driverClassName = driverClassName; | |
338 | + this.baseUrl = baseUrl; | |
339 | + this.defalutPort = defalutPort; | |
340 | + this.option = option; | |
341 | + } | |
342 | + | |
343 | + /** | |
344 | + * 한글값 | |
345 | + */ | |
346 | + final private String value; | |
347 | + | |
348 | + /** | |
349 | + * 드라이버 클래스 | |
350 | + */ | |
351 | + final private String driverClassName; | |
352 | + | |
353 | + /** | |
354 | + * 접속 URL | |
355 | + */ | |
356 | + final private String baseUrl; | |
357 | + | |
358 | + /** | |
359 | + * 기본 포트 | |
360 | + */ | |
361 | + final private String defalutPort; | |
362 | + | |
363 | + /** | |
364 | + * 접속 옵션 | |
365 | + */ | |
366 | + final private String option; | |
367 | + | |
368 | + | |
369 | + /** | |
370 | + * 한글값 조회 | |
371 | + */ | |
372 | + public String getValue () { | |
373 | + return value; | |
374 | + } | |
375 | + | |
376 | + /** | |
377 | + * 드라이버 클래스 조회 | |
378 | + */ | |
379 | + public String getDriverClassName () { | |
380 | + return driverClassName; | |
381 | + } | |
382 | + | |
383 | + /** | |
384 | + * 접속 URL 조회 | |
385 | + */ | |
386 | + public String getBaseUrl () { | |
387 | + return baseUrl; | |
388 | + } | |
389 | + | |
390 | + /** | |
391 | + * 기본 포트 조회 | |
392 | + */ | |
393 | + public String getDefaultPort () { | |
394 | + return defalutPort; | |
395 | + } | |
396 | + | |
397 | + /** | |
398 | + * 접속 옵션 조회 | |
399 | + */ | |
400 | + public String getOption () { | |
401 | + return option; | |
402 | + } | |
403 | + | |
404 | + /** | |
405 | + * 접속 URL 조회 | |
406 | + */ | |
407 | + public String getUrl (ConnectionDB connectionDB) { | |
408 | + StringBuilder builder = new StringBuilder(); | |
409 | + if ((this == ORACLE || this == TIBERO ) && connectionDB.isGroupDatabase() == false) { | |
410 | + builder.append(this.baseUrl); | |
411 | + builder.append(connectionDB.getConectIp()); | |
412 | + builder.append(":"); | |
413 | + builder.append(connectionDB.getConectPort()); | |
414 | + builder.append(":"); | |
415 | + builder.append(connectionDB.getDatabaseNm()); | |
416 | + } else { | |
417 | + builder.append(this.baseUrl); | |
418 | + builder.append(connectionDB.getConectIp()); | |
419 | + builder.append(":"); | |
420 | + builder.append(connectionDB.getConectPort()); | |
421 | + if(this == MSSQL) { | |
422 | + builder.append(";databaseName="); | |
423 | + }else { | |
424 | + builder.append("/"); | |
425 | + } | |
426 | + builder.append(connectionDB.getDatabaseNm()); | |
427 | + if (this == MYSQL) { | |
428 | + builder.append("?"); | |
429 | + builder.append(this.option.replaceAll("&", "&")); | |
430 | + }else if(this == POSTGRESQL) { | |
431 | + builder.append("?"); | |
432 | + builder.append("currentSchema="+connectionDB.getSchemaNm()); | |
433 | + } else if(this == MSSQL){ | |
434 | + builder.append(";"); | |
435 | + builder.append(this.option); | |
436 | + } | |
437 | + } | |
438 | + | |
439 | + return builder.toString(); | |
440 | + } | |
441 | + | |
442 | + /** | |
443 | + * 접속 URL 조회 | |
444 | + */ | |
445 | + public String getUrl (String ip, String port, String databaseName, boolean isGroupDatabase, String option) { | |
446 | + StringBuilder builder = new StringBuilder(); | |
447 | + if ((this == ORACLE || this == TIBERO ) && isGroupDatabase == false) { | |
448 | + builder.append(this.baseUrl); | |
449 | + builder.append(ip); | |
450 | + builder.append(":"); | |
451 | + builder.append(port); | |
452 | + builder.append(":"); | |
453 | + builder.append(databaseName); | |
454 | + } else { | |
455 | + builder.append(this.baseUrl); | |
456 | + builder.append(ip); | |
457 | + builder.append(":"); | |
458 | + builder.append(port); | |
459 | + builder.append("/"); | |
460 | + builder.append(databaseName); | |
461 | + } | |
462 | + | |
463 | + if (StringUtil.isEmpty(option) == false) { | |
464 | + builder.append("?"); | |
465 | + option.replaceAll("&", "&"); | |
466 | + builder.append(option); | |
467 | + } | |
468 | + | |
469 | + | |
470 | + return builder.toString(); | |
471 | + } | |
472 | + | |
473 | + /** | |
474 | + * 데이터 베이스 타입별 상수 목록 조회 | |
475 | + */ | |
476 | + public static Map<DatabaseType, String> getDatabaseTypeList () { | |
477 | + Map<DatabaseType, String> info = new LinkedHashMap<DatabaseType, String>(); | |
478 | + DatabaseType[] array = DatabaseType.values(); | |
479 | + for (int i = 0; i < array.length; i++) { | |
480 | + info.put(array[i], array[i].getValue()); | |
481 | + } | |
482 | + return info; | |
483 | + } | |
484 | + | |
485 | + /** | |
486 | + * 데이터 베이스 타입별 상수 목록 조회 | |
487 | + */ | |
488 | + public static Map<DatabaseType, Map<String, String>> getDatabaseTypeInfoList () { | |
489 | + Map<DatabaseType, Map<String, String>> info = new LinkedHashMap<DatabaseType, Map<String, String>>(); | |
490 | + DatabaseType[] array = DatabaseType.values(); | |
491 | + for (int i = 0; i < array.length; i++) { | |
492 | + Map<String, String> detailInfo = new HashMap<String, String>(); | |
493 | + detailInfo.put("key", array[i].toString()); | |
494 | + detailInfo.put("value", array[i].getValue()); | |
495 | + detailInfo.put("driverClassName", array[i].getDriverClassName()); | |
496 | + detailInfo.put("baseUrl", array[i].getBaseUrl()); | |
497 | + detailInfo.put("defalutPort", array[i].getDefaultPort()); | |
498 | + detailInfo.put("option", array[i].getOption()); | |
499 | + info.put(array[i], detailInfo); | |
500 | + } | |
501 | + return info; | |
502 | + } | |
503 | + | |
504 | + } | |
505 | + | |
506 | + | |
507 | + /** | |
508 | + * @author 최정우 | |
509 | + * @since 2019.11.13 | |
510 | + * | |
511 | + * SPMiner에서 등록되는 파일 타입과, 해당 파일 타입의 등록가능한 확장자를 정의한 상수 Class 입니다. | |
512 | + * 첨부파일, 이미지파일, 데이터 셋 파일 순서입니다. | |
513 | + */ | |
514 | + public enum FileType { | |
515 | + ALL_FILE(Arrays.asList("bmp","jpg","gif","png","jpeg","bmp","wma","avi","wav","mp3","mp4","mpeg","wmv","asf","pdf","ppt","pptx","docx","xls","xlsx","csv","hwp","txt","doc","zip", "json", "xml")) | |
516 | + , IMG_FILE(Arrays.asList("bmp","jpg","gif","png","jpeg")) | |
517 | + , DATASET_FILE(Arrays.asList("xls","xlsx","csv")); | |
518 | + | |
519 | + private FileType(List<String> extensions) { | |
520 | + this.extensions = extensions; | |
521 | + } | |
522 | + | |
523 | + /** | |
524 | + * 확장자 목록 | |
525 | + */ | |
526 | + final private List<String> extensions; | |
527 | + | |
528 | + /** | |
529 | + * 확장자 목록 조회 | |
530 | + */ | |
531 | + public List<String> getExtensions () { | |
532 | + return extensions; | |
533 | + } | |
534 | + } | |
535 | + | |
536 | + /** | |
537 | + * @author 김성훈 | |
538 | + * @since 2023.02.14 | |
539 | + * | |
540 | + * 업로드 파일에 대한 저장 폴더 경로를 정의한 상수 Class | |
541 | + * MAIN-메인 저장소, TEMP-임시 저장소 | |
542 | + */ | |
543 | + public enum FileUploadPath { | |
544 | + /* 관리 시스템 파일 업로드 경로 */ | |
545 | + //상대 경로 저장소(프로젝트 내부 -> Windows, Linux 구분 없음) | |
546 | + SFTP_RELATIVE_PATH("\\resources\\common\\file\\upload\\main", "/resources/common/file/upload/main") | |
547 | + //절대 경로 저장소(Windows, Linux) | |
548 | + , SFTP_ABSOLUTE_PATH("C:\\Taken_BI_Manager", "/home/Taken_BI_Manager") | |
549 | + , TEMP_ABSOLUTE_PATH("C:\\Taken_BI_Manager\\temp", "/home/Taken_BI_Manager/temp"); | |
550 | + | |
551 | + private FileUploadPath(String windowFileUploadPath, String linuxFileUploadPath) { | |
552 | + this.windowFileUploadPath = windowFileUploadPath; | |
553 | + this.linuxFileUploadPath = linuxFileUploadPath; | |
554 | + } | |
555 | + | |
556 | + final private String windowFileUploadPath; | |
557 | + | |
558 | + final private String linuxFileUploadPath; | |
559 | + | |
560 | + public String getWindowFileUploadPath() { | |
561 | + return windowFileUploadPath; | |
562 | + } | |
563 | + | |
564 | + public String getLinuxFileUploadPath() { | |
565 | + return linuxFileUploadPath; | |
566 | + } | |
567 | + | |
568 | + /** | |
569 | + * OS 타입별 파일 업로드 경로 return | |
570 | + */ | |
571 | + public String getOSFileUploadPath() { | |
572 | + if (System.getProperty("os.name").indexOf("Windows") > -1) { | |
573 | + return windowFileUploadPath; | |
574 | + } else { | |
575 | + return linuxFileUploadPath; | |
576 | + } | |
577 | + } | |
578 | + } | |
579 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/controller/cmmn/CommonController.java
... | ... | @@ -0,0 +1,126 @@ |
1 | +package com.takensoft.taken_bi_manager.controller.cmmn; | |
2 | + | |
3 | +import java.util.HashMap; | |
4 | + | |
5 | +import com.takensoft.taken_bi_manager.common.connection.api.vo.ConnectionApi; | |
6 | +import com.takensoft.taken_bi_manager.common.connection.ehojoPlus.vo.ConnectionEhojoVO; | |
7 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
8 | +import com.takensoft.taken_bi_manager.common.file.vo.FileInfo; | |
9 | +import com.takensoft.taken_bi_manager.common.schedule.vo.Schedule; | |
10 | +import com.takensoft.taken_bi_manager.common.stylesheet.vo.Background_style; | |
11 | +import com.takensoft.taken_bi_manager.common.stylesheet.vo.BorderStyle; | |
12 | +import com.takensoft.taken_bi_manager.common.stylesheet.vo.FontStyle; | |
13 | +import com.takensoft.taken_bi_manager.common.stylesheet.vo.StyleSheet; | |
14 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode; | |
15 | +import com.takensoft.taken_bi_manager.custom.vo.ComponentData; | |
16 | +import com.takensoft.taken_bi_manager.custom.vo.CustomComponentVO; | |
17 | +import com.takensoft.taken_bi_manager.custom.vo.CustomSplitterVO; | |
18 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
19 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
20 | +import com.takensoft.taken_bi_manager.data.vo.DatasetPost; | |
21 | +import com.takensoft.taken_bi_manager.diagram.vo.DiagramVO; | |
22 | +import com.takensoft.taken_bi_manager.diagram.vo.NodeVO; | |
23 | +import com.takensoft.taken_bi_manager.jobs.vo.JobGroup; | |
24 | +import com.takensoft.taken_bi_manager.jobs.vo.JobItm; | |
25 | +import com.takensoft.taken_bi_manager.jobs.vo.item.DataCheck; | |
26 | +import com.takensoft.taken_bi_manager.jobs.vo.item.DataFilter; | |
27 | +import com.takensoft.taken_bi_manager.jobs.vo.item.FilterItem; | |
28 | +import com.takensoft.taken_bi_manager.jobs.vo.item.JobItemGroup; | |
29 | +import com.takensoft.taken_bi_manager.meta.wrd.vo.StdWrd; | |
30 | +import com.takensoft.taken_bi_manager.openAPI.vo.ApiExportVO; | |
31 | +import com.takensoft.taken_bi_manager.openAPI.vo.OpenApiInfoVO; | |
32 | +import org.springframework.beans.factory.annotation.Autowired; | |
33 | +import org.springframework.web.bind.annotation.PostMapping; | |
34 | +import org.springframework.web.bind.annotation.RequestBody; | |
35 | +import org.springframework.web.bind.annotation.RequestMapping; | |
36 | +import org.springframework.web.bind.annotation.RestController; | |
37 | + | |
38 | +import com.takensoft.taken_bi_manager.common.code.service.CmmnCodeService; | |
39 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
40 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType; | |
41 | + | |
42 | +@RestController | |
43 | +@RequestMapping("/common") | |
44 | +public class CommonController { | |
45 | + | |
46 | + @Autowired | |
47 | + private CmmnCodeService cmmnCodeService; | |
48 | + | |
49 | + | |
50 | + /* | |
51 | + * 공통코드 리스트 요청 | |
52 | + */ | |
53 | + @PostMapping(path = "/getCodeList.json") | |
54 | + public CustomeResultMap getCodeList(@RequestBody HashMap<String, Object> params) throws Exception { | |
55 | + | |
56 | + CustomeResultMap map = new CustomeResultMap(); | |
57 | + | |
58 | + // 코드리스트 | |
59 | + map.getResultData().put("codeList",cmmnCodeService.getCodeListByGroupId(params.get("groupCode").toString())); | |
60 | + | |
61 | + | |
62 | + return map; | |
63 | + } | |
64 | + | |
65 | + | |
66 | + @PostMapping(path = "/getDataBaseTypeList.json") | |
67 | + public CustomeResultMap getDataBaseTypeList() throws Exception { | |
68 | + | |
69 | + CustomeResultMap map = new CustomeResultMap(); | |
70 | + // 코드리스트 | |
71 | + map.getResultData().put("DatabaseTypeList", DatabaseType.getDatabaseTypeInfoList()); | |
72 | + | |
73 | + return map; | |
74 | + } | |
75 | + | |
76 | + /* | |
77 | + * 데이터 베이스 접속 체크 | |
78 | + */ | |
79 | + @PostMapping(path = "/getDefaultObject.json") | |
80 | + public CustomeResultMap getDefaultObject() throws Exception { | |
81 | + CustomeResultMap map = new CustomeResultMap(); | |
82 | + | |
83 | + // 잡그룹 처리 아이템 | |
84 | + map.getResultData().put("jobGroup", new JobGroup()); | |
85 | + map.getResultData().put("jobItem", new JobItm()); | |
86 | + map.getResultData().put("connectionDb", new ConnectionDB()); | |
87 | + map.getResultData().put("fileRead", new FileInfo()); // 하석형 추가 | |
88 | + | |
89 | + // API 추가 | |
90 | + map.getResultData().put("connectionApi", new ConnectionApi()); | |
91 | + map.getResultData().put("dataTable", new DataTable()); | |
92 | + map.getResultData().put("dataCheck", new DataCheck()); | |
93 | + map.getResultData().put("schedule", new Schedule()); | |
94 | + map.getResultData().put("dataset", new Dataset()); | |
95 | + map.getResultData().put("datasetPost", new DatasetPost()); | |
96 | + map.getResultData().put("filterItem", new FilterItem()); | |
97 | + map.getResultData().put("dataFilter", new DataFilter()); | |
98 | + map.getResultData().put("dataTypeList", SystemCode.DataType.getDataTypeArray()); | |
99 | + map.getResultData().put("jobItemGroup", new JobItemGroup()); | |
100 | + map.getResultData().put("connectionEhojo", new ConnectionEhojoVO()); | |
101 | + | |
102 | + // 메타데이터 표준단어 | |
103 | + map.getResultData().put("stdWrm", new StdWrd()); | |
104 | + | |
105 | + // NODE 아이템 | |
106 | + map.getResultData().put("diagram", new DiagramVO()); | |
107 | + map.getResultData().put("node", new NodeVO()); | |
108 | + | |
109 | + // 레이아웃 처리 아이템 | |
110 | + map.getResultData().put("customSplitter", new CustomSplitterVO()); | |
111 | + map.getResultData().put("component", new CustomComponentVO()); | |
112 | + map.getResultData().put("componentData", new ComponentData()); | |
113 | + | |
114 | + // openAPI | |
115 | + map.getResultData().put("openApiInfo", new OpenApiInfoVO()); | |
116 | + map.getResultData().put("apiExport", new ApiExportVO()); | |
117 | + | |
118 | + // 스타일 시트 | |
119 | + map.getResultData().put("styleSheet", new StyleSheet()); | |
120 | + map.getResultData().put("borderStyle", new BorderStyle()); | |
121 | + map.getResultData().put("fontStyle", new FontStyle()); | |
122 | + map.getResultData().put("background_style", new Background_style()); | |
123 | + | |
124 | + return map; | |
125 | + } | |
126 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/controller/cmmn/ScheduleController.java
... | ... | @@ -0,0 +1,65 @@ |
1 | +package com.takensoft.taken_bi_manager.controller.cmmn; | |
2 | + | |
3 | +import com.takensoft.taken_bi_manager.common.schedule.service.ScheduleService; | |
4 | +import com.takensoft.taken_bi_manager.common.schedule.vo.Schedule; | |
5 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
6 | +import com.takensoft.taken_bi_manager.common.vo.SearchVO; | |
7 | +import org.springframework.beans.factory.annotation.Autowired; | |
8 | +import org.springframework.web.bind.annotation.*; | |
9 | + | |
10 | +@RestController | |
11 | +@RequestMapping("/schedule") | |
12 | +public class ScheduleController { | |
13 | + @Autowired | |
14 | + private ScheduleService scheduleService; | |
15 | + | |
16 | + /* | |
17 | + * 스케줄 등록 | |
18 | + */ | |
19 | + @PostMapping(path = "/conflictInsertSchedule.json") | |
20 | + public CustomeResultMap conflictInsertSchedule(@RequestBody Schedule schedule) throws Exception { | |
21 | + CustomeResultMap map = new CustomeResultMap(); | |
22 | + scheduleService.conflictInsertSchedule(schedule); | |
23 | + return map; | |
24 | + } | |
25 | + | |
26 | + /* | |
27 | + * 스케줄 목록 조회 | |
28 | + */ | |
29 | + @PostMapping(path = "/selectScheduleList.json") | |
30 | + public CustomeResultMap selectScheduleList(@RequestBody SearchVO searchVO) throws Exception { | |
31 | + return scheduleService.selectScheduleList(searchVO); | |
32 | + } | |
33 | + | |
34 | + /* | |
35 | + * 스케줄 상세 조회 | |
36 | + */ | |
37 | + @PostMapping(path = "/selectSchedule.json") | |
38 | + public CustomeResultMap selectSchedule(@RequestBody Schedule schedule) throws Exception { | |
39 | + CustomeResultMap map = new CustomeResultMap(); | |
40 | + map.getResultData().put("schedule", scheduleService.selectSchedule(schedule)); | |
41 | + return map; | |
42 | + } | |
43 | + | |
44 | + /** | |
45 | + * @author 박정하 | |
46 | + * @since 2024.10.04 | |
47 | + * | |
48 | + * 스케줄 정보 삭제 | |
49 | + */ | |
50 | + @GetMapping(value="/deleteSchedule/{schdulId}") | |
51 | + public CustomeResultMap deleteSchedule(@PathVariable String schdulId) throws Exception { | |
52 | + return scheduleService.deleteSchedule(schdulId); | |
53 | + } | |
54 | + | |
55 | + /** | |
56 | + * @author 박정하 | |
57 | + * @since 2024.10.04 | |
58 | + * | |
59 | + * 스케줄 상태 변경 | |
60 | + */ | |
61 | + @GetMapping(value="/scheduleSttusChange/{schdulId}/{schdulSttus}") | |
62 | + public CustomeResultMap scheduleSttusChange(@PathVariable String schdulId, @PathVariable String schdulSttus) throws Exception { | |
63 | + return scheduleService.scheduleSttusChange(schdulId, schdulSttus); | |
64 | + } | |
65 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/controller/data/DataController.java
... | ... | @@ -0,0 +1,175 @@ |
1 | +package com.takensoft.taken_bi_manager.controller.data; | |
2 | + | |
3 | +import com.fasterxml.jackson.core.type.TypeReference; | |
4 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
5 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
6 | +import com.takensoft.taken_bi_manager.jobs.service.JobService; | |
7 | +import com.takensoft.taken_bi_manager.jobs.vo.JobGroup; | |
8 | +import org.springframework.beans.factory.annotation.Autowired; | |
9 | +import org.springframework.web.bind.annotation.GetMapping; | |
10 | +import org.springframework.web.bind.annotation.ModelAttribute; | |
11 | +import org.springframework.web.bind.annotation.PostMapping; | |
12 | +import org.springframework.web.bind.annotation.RequestBody; | |
13 | +import org.springframework.web.bind.annotation.RequestMapping; | |
14 | +import org.springframework.web.bind.annotation.RestController; | |
15 | + | |
16 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
17 | +import com.takensoft.taken_bi_manager.common.code.service.CmmnCodeService; | |
18 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
19 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
20 | +import com.takensoft.taken_bi_manager.common.vo.SearchVO; | |
21 | +import com.takensoft.taken_bi_manager.common.vo.SystemCode.DatabaseType; | |
22 | +import com.takensoft.taken_bi_manager.data.service.DataService; | |
23 | +import com.takensoft.taken_bi_manager.user.member.servie.LoginService; | |
24 | +import com.takensoft.taken_bi_manager.user.member.vo.Member; | |
25 | + | |
26 | +import java.util.List; | |
27 | +import java.util.Map; | |
28 | + | |
29 | +@RestController | |
30 | +@RequestMapping("/data") | |
31 | +public class DataController { | |
32 | + | |
33 | + @Autowired | |
34 | + private CmmnCodeService cmmnCodeService; | |
35 | + | |
36 | + @Autowired | |
37 | + private DataService dataService; | |
38 | + | |
39 | + @Autowired | |
40 | + private JobService jobService; | |
41 | + | |
42 | + /* | |
43 | + * 데이터 베이스 접속 체크 | |
44 | + */ | |
45 | + @PostMapping(path = "/dataBaseConnectionCheck.json") | |
46 | + public CustomeResultMap dataBaseConnectionCheck(@RequestBody ConnectionDB connectionDB) throws Exception { | |
47 | + | |
48 | + CustomeResultMap map = new CustomeResultMap(); | |
49 | + | |
50 | + return dataService.dbConnectionCheck(connectionDB); | |
51 | + } | |
52 | + | |
53 | + /* | |
54 | + * 데이터 베이스 접속 체크 | |
55 | + */ | |
56 | + @PostMapping(path = "/checkTableName.json") | |
57 | + public CustomeResultMap checkTableName(@RequestBody Map<String,Object> jsonObject) throws Exception { | |
58 | + | |
59 | + CustomeResultMap map = new CustomeResultMap(); | |
60 | + | |
61 | + ObjectMapper mapper = new ObjectMapper(); | |
62 | + | |
63 | + ConnectionDB connectionDB = mapper.convertValue(jsonObject.get("connectionDB"), ConnectionDB.class); | |
64 | + | |
65 | + return dataService.checkTableName(jsonObject.get("tableNm").toString(),connectionDB); | |
66 | + } | |
67 | + | |
68 | + /* | |
69 | + * 데이터 베이스 테이블 리스트 조회 | |
70 | + */ | |
71 | + @PostMapping(path = "/selectTableList.json") | |
72 | + public CustomeResultMap selectTableList(@RequestBody ConnectionDB connectionDB) throws Exception { | |
73 | + | |
74 | + CustomeResultMap map = new CustomeResultMap(); | |
75 | + | |
76 | + return dataService.selectTableList(connectionDB); | |
77 | + } | |
78 | + | |
79 | + /* | |
80 | + * 디비 커넥션 정보 저장, 수정, 삭제 | |
81 | + */ | |
82 | + @PostMapping(path = "/insertDbConnection.json") | |
83 | + public CustomeResultMap insertDbConnection(@RequestBody ConnectionDB connectionDB) throws Exception { | |
84 | + | |
85 | + return dataService.conflictInsertDbConnection(connectionDB); | |
86 | + } | |
87 | + | |
88 | + /* | |
89 | + * 디비 커넥션 정보 저장, 수정, 삭제 | |
90 | + */ | |
91 | + @PostMapping(path = "/selectDbConnectionList.json") | |
92 | + public CustomeResultMap selectDbConnectionList(@RequestBody SearchVO searchVO) throws Exception { | |
93 | + | |
94 | + return dataService.selectDbConnectionList(searchVO); | |
95 | + }/* | |
96 | + * 디비 커넥션 정보 저장, 수정, 삭제 | |
97 | + */ | |
98 | + @PostMapping(path = "/selectDbConnectionOne.json") | |
99 | + public CustomeResultMap selectDbConnectionOne(@RequestBody Map<String, Object> jsonObject) throws Exception { | |
100 | + | |
101 | + CustomeResultMap map = new CustomeResultMap(); | |
102 | + | |
103 | + map.getResultData().put("dbConnection",dataService.selectDbConnectionOne(jsonObject.get("dbConectId").toString())); | |
104 | + | |
105 | + return map; | |
106 | + } | |
107 | + | |
108 | + | |
109 | + | |
110 | + /* | |
111 | + * 테이블 내용 가져오기 | |
112 | + */ | |
113 | + @PostMapping(path = "/getTableData.json") | |
114 | + public CustomeResultMap getTableData(@RequestBody Map<String, Object> jsonObject) throws Exception { | |
115 | + | |
116 | + ObjectMapper mapper = new ObjectMapper(); | |
117 | + | |
118 | + Dataset dataset = mapper.convertValue(jsonObject.get("dataset"), Dataset.class); | |
119 | + ConnectionDB connectionDB = mapper.convertValue(jsonObject.get("connectionDB"), ConnectionDB.class); | |
120 | + DataTable dataTable = new DataTable(dataset); | |
121 | + | |
122 | + return dataService.getTableData(connectionDB,dataTable,false); | |
123 | + } | |
124 | + | |
125 | + /* | |
126 | + * 테이블 내용 가져오기 | |
127 | + */ | |
128 | + @PostMapping(path = "/getTableDataByQuery.json") | |
129 | + public CustomeResultMap getTableDataByQuery(@RequestBody Map<String, Object> jsonObject) throws Exception { | |
130 | + | |
131 | + ObjectMapper mapper = new ObjectMapper(); | |
132 | + | |
133 | + DataTable dataTable = mapper.convertValue(jsonObject.get("dataTable"), DataTable.class); | |
134 | + ConnectionDB connectionDB = mapper.convertValue(jsonObject.get("connectionDB"), ConnectionDB.class); | |
135 | + | |
136 | + return dataService.getTableData(connectionDB,dataTable,true); | |
137 | + } | |
138 | + | |
139 | + /* | |
140 | + * 테이블 내용 가져오기 | |
141 | + */ | |
142 | + @PostMapping(path = "/changeDatasetRows.json") | |
143 | + public CustomeResultMap changeDatasetRows(@RequestBody Map<String, Object> jsonObject) throws Exception { | |
144 | + | |
145 | + ObjectMapper mapper = new ObjectMapper(); | |
146 | + | |
147 | + List<List<Object>> changeData = mapper.convertValue(jsonObject.get("changeData"), new TypeReference<List<List<Object>>>(){}); | |
148 | + List<List<Object>> deleteData = mapper.convertValue(jsonObject.get("deleteData"), new TypeReference<List<List<Object>>>(){}); | |
149 | + List<List<Object>> insertData = mapper.convertValue(jsonObject.get("insertData"), new TypeReference<List<List<Object>>>(){}); | |
150 | + | |
151 | + JobGroup jobGroup = mapper.convertValue(jsonObject.get("jobGroup"), JobGroup.class); | |
152 | + | |
153 | + CustomeResultMap map = dataService.datasetRowDataUpdate(jsonObject.get("datasetPost_id").toString(), changeData, deleteData, insertData, "user"); | |
154 | + map.getResultData().put("dataTable", jobService.excuteJob(jobGroup).getDataTable()); | |
155 | + | |
156 | + return map; | |
157 | + } | |
158 | + | |
159 | + | |
160 | + /* | |
161 | + * 디비 커넥션 정보, 삭제 | |
162 | + */ | |
163 | + @PostMapping(path = "/deleteConnectionDb.json") | |
164 | + public CustomeResultMap deleteConnectionDb(@RequestBody Map<String, Object> jsonObject) throws Exception { | |
165 | + | |
166 | + CustomeResultMap map = new CustomeResultMap(); | |
167 | + | |
168 | + map.getResultData().put("dbConnection",dataService.deleteConnectionDb(jsonObject.get("dbConectId").toString())); | |
169 | + | |
170 | + return map; | |
171 | + } | |
172 | + | |
173 | + | |
174 | + | |
175 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/controller/data/DatasetController.java
... | ... | @@ -0,0 +1,102 @@ |
1 | +package com.takensoft.taken_bi_manager.controller.data; | |
2 | + | |
3 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
4 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
5 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
6 | +import com.takensoft.taken_bi_manager.common.vo.SearchVO; | |
7 | +import com.takensoft.taken_bi_manager.data.service.DatasetService; | |
8 | +import com.takensoft.taken_bi_manager.data.vo.Dataset; | |
9 | +import com.takensoft.taken_bi_manager.data.vo.DatasetPost; | |
10 | +import com.takensoft.taken_bi_manager.jobs.vo.JobItm; | |
11 | +import org.springframework.beans.factory.annotation.Autowired; | |
12 | +import org.springframework.web.bind.annotation.PostMapping; | |
13 | +import org.springframework.web.bind.annotation.RequestBody; | |
14 | +import org.springframework.web.bind.annotation.RequestMapping; | |
15 | +import org.springframework.web.bind.annotation.RestController; | |
16 | +import org.springframework.web.servlet.ModelAndView; | |
17 | + | |
18 | +import java.util.Map; | |
19 | + | |
20 | +@RestController | |
21 | +@RequestMapping("/dataset") | |
22 | +public class DatasetController { | |
23 | + | |
24 | + @Autowired | |
25 | + private DatasetService datasetService; | |
26 | + | |
27 | + /* | |
28 | + * 테이블 내용 가져오기 | |
29 | + */ | |
30 | + @PostMapping(path = "/insertDataPost.json") | |
31 | + public CustomeResultMap insertDataPost(@RequestBody Map<String, Object> jsonObject) throws Exception { | |
32 | + ObjectMapper mapper = new ObjectMapper(); | |
33 | + DatasetPost datasetPost = mapper.convertValue(jsonObject.get("datasetPost"), DatasetPost.class); | |
34 | + Dataset dataset = mapper.convertValue(jsonObject.get("dataset"), Dataset.class); | |
35 | + ConnectionDB connectionDB = mapper.convertValue(jsonObject.get("connectionDB"), ConnectionDB.class); | |
36 | + JobItm jobItm = mapper.convertValue(jsonObject.get("JobItm"), JobItm.class); | |
37 | + String hostCode = mapper.convertValue(jsonObject.get("hostCode"), String.class); | |
38 | + return datasetService.insertDataPost(datasetPost, dataset, connectionDB, jobItm, hostCode); | |
39 | + } | |
40 | + | |
41 | + /* | |
42 | + * 테이블 내용 가져오기 | |
43 | + */ | |
44 | + @PostMapping(path = "/updateDataPost.json") | |
45 | + public CustomeResultMap updateDataPost(@RequestBody Map<String, Object> jsonObject) throws Exception { | |
46 | + ObjectMapper mapper = new ObjectMapper(); | |
47 | + DatasetPost datasetPost = mapper.convertValue(jsonObject.get("datasetPost"), DatasetPost.class); | |
48 | + Dataset dataset = mapper.convertValue(jsonObject.get("dataset"), Dataset.class); | |
49 | + return datasetService.updateDataPost(datasetPost,dataset); | |
50 | + } | |
51 | + | |
52 | + /* | |
53 | + * 데이타셋 포스트 리스트 호출 | |
54 | + */ | |
55 | + @PostMapping(path = "/selectDataPostList.json") | |
56 | + public CustomeResultMap selectDataPostList(@RequestBody SearchVO searchVO) throws Exception { | |
57 | + return datasetService.selectDatasetPostList(searchVO); | |
58 | + } | |
59 | + | |
60 | + /* | |
61 | + * 데이터셋 상세 내용 호출 | |
62 | + */ | |
63 | + @PostMapping(path = "/selectDataPost.json") | |
64 | + public CustomeResultMap selectDataPost(@RequestBody Map<String, Object> jsonObject) throws Exception { | |
65 | + ObjectMapper mapper = new ObjectMapper(); | |
66 | + SearchVO searchVO = mapper.convertValue(jsonObject.get("search"), SearchVO.class); | |
67 | + return datasetService.selectDatasetPost((String) jsonObject.get("datapost_id"), searchVO); | |
68 | + } | |
69 | + | |
70 | + /* | |
71 | + * 데이터셋 상세 내용 호출 | |
72 | + */ | |
73 | + @PostMapping(path = "/getDataTableInfo.json") | |
74 | + public CustomeResultMap getDataTableInfo(@RequestBody Map<String, Object> jsonObject) throws Exception { | |
75 | + return datasetService.getDataTableInfo(jsonObject.get("datapost_id").toString()); | |
76 | + } | |
77 | + | |
78 | + /* | |
79 | + * 컴럼 정보 변경 | |
80 | + */ | |
81 | + @RequestMapping(value = "/changeColumnInfo.json") | |
82 | + public CustomeResultMap changeColumnInfo (@RequestBody Map<String, Object> jsonObject) throws Exception { | |
83 | + CustomeResultMap map = new CustomeResultMap(); | |
84 | + try { | |
85 | + map = datasetService.changeColumnInfo(jsonObject); | |
86 | + }catch (Exception e){ | |
87 | + map.getCheckMessage().setError(e.getMessage()); | |
88 | + } | |
89 | + // mav.addObject("columnDatas",datasetService.getColumnDatas(jsonObject.get("datasetId"))); | |
90 | + return map; | |
91 | + } | |
92 | + | |
93 | + /* | |
94 | + * 데이터셋 데이터 포스트 삭제 | |
95 | + */ | |
96 | + @RequestMapping(value = "/deleteDataPost.json") | |
97 | + public CustomeResultMap deleteDataPost (@RequestBody Map<String, Object> jsonObject) throws Exception { | |
98 | + ObjectMapper mapper = new ObjectMapper(); | |
99 | + DatasetPost datasetPost = mapper.convertValue(jsonObject.get("datasetPost"), DatasetPost.class); | |
100 | + return datasetService.deleteDataPost(datasetPost); | |
101 | + } | |
102 | +}(파일 끝에 줄바꿈 문자 없음) |
+++ src/main/java/com/takensoft/taken_bi_manager/controller/jobs/JobController.java
... | ... | @@ -0,0 +1,97 @@ |
1 | +package com.takensoft.taken_bi_manager.controller.jobs; | |
2 | + | |
3 | + | |
4 | +import com.takensoft.taken_bi_manager.common.file.vo.FileInfo; | |
5 | +import com.takensoft.taken_bi_manager.common.schedule.vo.Schedule; | |
6 | +import com.takensoft.taken_bi_manager.common.vo.SearchVO; | |
7 | +import com.takensoft.taken_bi_manager.data.service.DataService; | |
8 | +import com.takensoft.taken_bi_manager.data.vo.DataTable; | |
9 | +import com.takensoft.taken_bi_manager.jobs.service.JobService; | |
10 | +import com.takensoft.taken_bi_manager.jobs.vo.item.DataCheck; | |
11 | +import org.springframework.beans.factory.annotation.Autowired; | |
12 | +import org.springframework.web.bind.annotation.PostMapping; | |
13 | +import org.springframework.web.bind.annotation.RequestBody; | |
14 | +import org.springframework.web.bind.annotation.RequestMapping; | |
15 | +import org.springframework.web.bind.annotation.RestController; | |
16 | + | |
17 | +import com.takensoft.taken_bi_manager.common.connection.db.vo.ConnectionDB; | |
18 | +import com.takensoft.taken_bi_manager.common.vo.CustomeResultMap; | |
19 | +import com.takensoft.taken_bi_manager.jobs.vo.JobGroup; | |
20 | +import com.takensoft.taken_bi_manager.jobs.vo.JobItm; | |
21 | + | |
22 | +import java.util.HashMap; | |
23 | + | |
24 | + | |
25 | +@RestController | |
26 | +@RequestMapping("/job") | |
27 | +public class JobController { | |
28 | + | |
29 | + | |
30 | + @Autowired | |
31 | + private JobService jobService; | |
32 | + | |
33 | + | |
34 | + /* | |
35 | + * 데이터 베이스 접속 체크 | |
36 | + */ | |
37 | + @PostMapping(path = "/getDefaultJobGroup.json") | |
38 | + public CustomeResultMap getDefaultJobGroup() throws Exception { | |
39 | + CustomeResultMap map = new CustomeResultMap(); | |
40 | + map.getResultData().put("jobGroup", new JobGroup()); | |
41 | + map.getResultData().put("jobItem", new JobItm()); | |
42 | + map.getResultData().put("connectionDb", new ConnectionDB()); | |
43 | + map.getResultData().put("fileRead", new FileInfo()); // 하석형 추가 | |
44 | + map.getResultData().put("dataTable", new DataTable()); | |
45 | + map.getResultData().put("dataCheck", new DataCheck()); | |
46 | + map.getResultData().put("schedule", new Schedule()); | |
47 | + | |
48 | + return map; | |
49 | + } | |
50 | + | |
51 | + /* | |
52 | + * 데이터 베이스 접속 체크 | |
53 | + */ | |
54 | + @PostMapping(path = "/executeJob.json") | |
55 | + public CustomeResultMap executeJob(@RequestBody JobGroup jobGroup) throws Exception { | |
56 | + | |
57 | + CustomeResultMap map = new CustomeResultMap(); | |
58 | + map.getResultData().put("dataTable",jobService.excuteJob(jobGroup).getDataTable()); | |
59 | + return map; | |
60 | + } | |
61 | + | |
62 | + /* | |
63 | + * 내부 DB 잡그룹 생성 | |
64 | + */ | |
65 | + @PostMapping(path = "/createJobGroup.json") | |
66 | + public CustomeResultMap createJobGroup(@RequestBody JobGroup jobGroup) throws Exception { | |
67 | + | |
68 | + CustomeResultMap map = new CustomeResultMap(); | |
69 | + | |
70 | + map.getResultData().put("jobGroup",jobService.excuteJob(jobGroup)); | |
71 | + return map; | |
72 | + } | |
73 | + | |
74 | + /* | |
75 | + * 데이터 베이스 접속 체크 | |
76 | + */ | |
77 | + @PostMapping(path = "/insertJobGroup.json") | |
78 | + public CustomeResultMap insertJobGroup(@RequestBody JobGroup jobGroup) throws Exception { | |
79 | + | |
80 | + return jobService.insertJobGroup(jobGroup); | |
81 | + } | |
82 | + | |
83 | + /* | |
84 | + * 데이터 베이스 접속 체크 | |
85 | + */ | |
86 | + @PostMapping(path = "/selectJobGroup.json") | |
87 | + public CustomeResultMap selectJobGroup(@RequestBody HashMap<String, Object> params) throws Exception { | |
88 | + | |
89 | + CustomeResultMap map = new CustomeResultMap(); | |
90 | + map.getResultData().put("jobGroup",jobService.selectJobGroup(params.get("group_id").toString())); | |
91 | + | |
92 | + return map; | |
93 | + } | |
94 | + | |
95 | + | |
96 | + | |
97 | +} |
+++ src/main/java/com/takensoft/taken_bi_manager/controller/login/LoginController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/controller/meta/management/MetaManageController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/controller/meta/wrd/WrdController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/dao/CustomDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/service/CustomService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/service/impl/CustomServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/ComponentColumn.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/ComponentData.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/ComponentJobGroupVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/ComponentTitleVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomComponentVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomPageVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomSplitterColumnOptionVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomSplitterOptionVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/CustomSplitterVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/ErrorRes.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/vo/JobFlowVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/web/CustomController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/web/CustomException.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/custom/web/GlobalExceptionHandler.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/dao/DataDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/dao/DatasetDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/service/DataService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/service/DataTableService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/service/DatasetService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/service/impl/DataServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/service/impl/DataTableServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/service/impl/DatasetServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/util/DataTableConvert.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/util/DataUtil.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/Column.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/ColumnData.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/ColumnValue.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/DataTable.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/Dataset.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/DatasetPost.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/data/vo/DatasetPostLog.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/department/dao/DepartmentDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/department/dao/DeptHostDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/department/service/DepartmentService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/department/service/DeptHostService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/department/service/Impl/DepartmentServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/department/service/Impl/DeptHostServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/department/vo/DepartmentVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/department/vo/DeptHostVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/department/vo/OrgnztAuthorVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/department/vo/OrgnztMemberVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/department/web/DepartmentController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/department/web/DeptHostController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/dao/DiagramDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/dto/DiagramDetailDTO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/dto/DiagramListDTO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/service/Diagramservice.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/service/FilterService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/service/impl/DiagramServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/service/impl/FilterServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/vo/DiagramVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/vo/EdgeVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/vo/LogDetailVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/vo/LogVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/vo/NodePosition.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/vo/NodeVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/web/DiagramController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/web/FilterController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/diagram/web/ScheduleOperator.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/host/dao/HostDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/host/dao/SftpDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/host/service/HostService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/host/service/SftpService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/host/service/impl/SftpServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/host/vo/ConnectionVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/host/vo/FilesVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/host/vo/HostVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/host/vo/SftpVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/host/web/HostController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/host/web/SftpController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/dao/JobDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/service/JobService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/service/impl/JobServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/util/DataFilterUtil.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/util/JobUtil.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/JobGroup.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/JobItm.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/DataCheck.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/DataCheckItem.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/DataFilter.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/DatasetWriteItem.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/FileInfoItem.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/FilterItem.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/JobItemGroup.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/jobs/vo/item/JobReadConItm.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/meta/management/dao/MetaManageDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/meta/management/service/MetaManageService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/meta/management/service/impl/MetaManageServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/meta/wrd/dao/StdWrdDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/meta/wrd/service/StdWrdService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/meta/wrd/service/impl/StdWrdServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/meta/wrd/vo/StdWrd.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/meta/wrd/vo/StdWrdSearch.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/dao/OpenApiDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/service/OpenApiService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/service/impl/OpenApiServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/ApiConnectVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/ApiExportVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/ApiParamVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/GisInfoVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/OpenApiInfoVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/vo/OpenApiKeyVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/openAPI/web/OpenApiController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/push/dao/PushDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/push/dao/WebPushDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/push/service/WebPushService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/push/service/impl/WebPushServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/PushResultVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/PushTokenLogVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/PushTokenVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/PushUserVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/PushVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/_PushResultVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/push/vo/_PushVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/push/web/WebPushController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/dao/LoginDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/dao/MemberDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/dao/MyPageDAO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/LoginService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/MemberService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/MyPageService.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/impl/LoginServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/impl/MemberServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/servie/impl/MyPageServiceImpl.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/vo/AuthorVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/vo/Member.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/vo/MemberHistory.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/vo/UserAuthorVO.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/web/MemberController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/member/web/MyPageController.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/org/vo/Organization.java
This diff is skipped because there are too many other diffs. |
+++ src/main/java/com/takensoft/taken_bi_manager/user/org/vo/OrganizationHistory.java
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/application.properties
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/log4j2.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/log4jdbc.log4j2.properties
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/api/connect-ehojo-plus-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/api/connection-api-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/common/commonCode-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/common/file-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/common/schedule-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/custom/custom-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/data/data-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/data/dataset-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/department/department-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/department/deptHost-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/host/host-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/host/sftp-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/job/job-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/meta/stdwrd-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/mybatis-config.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/openAPI/openApi-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/postgres/diagram-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/push/push-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/sql/mariadb-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/sql/mssql-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/sql/mysql-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/sql/oracle-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/sql/postgre-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/sql/tibero-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/user/login-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/user/member-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/spring/mapper/user/mypage-SQL.xml
This diff is skipped because there are too many other diffs. |
+++ src/main/resources/static/index.html
This diff is skipped because there are too many other diffs. |
+++ src/main/webapp/META-INF/MANIFEST.MF
This diff is skipped because there are too many other diffs. |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?