浏览代码

first commit

shjung 3 年之前
当前提交
16d41a8fe3

+ 34 - 0
.gitignore

@@ -0,0 +1,34 @@
+HELP.md
+target/
+logs/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 118 - 0
.mvn/wrapper/MavenWrapperDownloader.java

@@ -0,0 +1,118 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+    private static final String WRAPPER_VERSION = "0.5.6";
+    /**
+     * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+     */
+    private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+            + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+    /**
+     * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+     * use instead of the default one.
+     */
+    private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+            ".mvn/wrapper/maven-wrapper.properties";
+
+    /**
+     * Path where the maven-wrapper.jar will be saved to.
+     */
+    private static final String MAVEN_WRAPPER_JAR_PATH =
+            ".mvn/wrapper/maven-wrapper.jar";
+
+    /**
+     * Name of the property which should be used to override the default download url for the wrapper.
+     */
+    private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+    public static void main(String args[]) {
+        System.out.println("- Downloader started");
+        File baseDirectory = new File(args[0]);
+        System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+        // If the maven-wrapper.properties exists, read it and check if it contains a custom
+        // wrapperUrl parameter.
+        File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+        String url = DEFAULT_DOWNLOAD_URL;
+        if (mavenWrapperPropertyFile.exists()) {
+            FileInputStream mavenWrapperPropertyFileInputStream = null;
+            try {
+                mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+                Properties mavenWrapperProperties = new Properties();
+                mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+                url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+            } catch (IOException e) {
+                System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+            } finally {
+                try {
+                    if (mavenWrapperPropertyFileInputStream != null) {
+                        mavenWrapperPropertyFileInputStream.close();
+                    }
+                } catch (IOException e) {
+                    // Ignore ...
+                }
+            }
+        }
+        System.out.println("- Downloading from: " + url);
+
+        File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+        if (!outputFile.getParentFile().exists()) {
+            if (!outputFile.getParentFile().mkdirs()) {
+                System.out.println(
+                        "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+            }
+        }
+        System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+        try {
+            downloadFileFromURL(url, outputFile);
+            System.out.println("Done");
+            System.exit(0);
+        } catch (Throwable e) {
+            System.out.println("- Error downloading");
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+
+    private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+        if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+            String username = System.getenv("MVNW_USERNAME");
+            char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+            Authenticator.setDefault(new Authenticator() {
+                @Override
+                protected PasswordAuthentication getPasswordAuthentication() {
+                    return new PasswordAuthentication(username, password);
+                }
+            });
+        }
+        URL website = new URL(urlString);
+        ReadableByteChannel rbc;
+        rbc = Channels.newChannel(website.openStream());
+        FileOutputStream fos = new FileOutputStream(destination);
+        fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+        fos.close();
+        rbc.close();
+    }
+
+}

二进制
.mvn/wrapper/maven-wrapper.jar


+ 2 - 0
.mvn/wrapper/maven-wrapper.properties

@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar

+ 322 - 0
mvnw

@@ -0,0 +1,322 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   M2_HOME - location of maven2's installed home dir
+#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
+#     e.g. to debug Maven itself, use
+#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ]; then
+
+  if [ -f /etc/mavenrc ]; then
+    . /etc/mavenrc
+  fi
+
+  if [ -f "$HOME/.mavenrc" ]; then
+    . "$HOME/.mavenrc"
+  fi
+
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false
+darwin=false
+mingw=false
+case "$(uname)" in
+CYGWIN*) cygwin=true ;;
+MINGW*) mingw=true ;;
+Darwin*)
+  darwin=true
+  # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+  # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+  if [ -z "$JAVA_HOME" ]; then
+    if [ -x "/usr/libexec/java_home" ]; then
+      export JAVA_HOME="$(/usr/libexec/java_home)"
+    else
+      export JAVA_HOME="/Library/Java/Home"
+    fi
+  fi
+  ;;
+esac
+
+if [ -z "$JAVA_HOME" ]; then
+  if [ -r /etc/gentoo-release ]; then
+    JAVA_HOME=$(java-config --jre-home)
+  fi
+fi
+
+if [ -z "$M2_HOME" ]; then
+  ## resolve links - $0 may be a link to maven's home
+  PRG="$0"
+
+  # need this for relative symlinks
+  while [ -h "$PRG" ]; do
+    ls=$(ls -ld "$PRG")
+    link=$(expr "$ls" : '.*-> \(.*\)$')
+    if expr "$link" : '/.*' >/dev/null; then
+      PRG="$link"
+    else
+      PRG="$(dirname "$PRG")/$link"
+    fi
+  done
+
+  saveddir=$(pwd)
+
+  M2_HOME=$(dirname "$PRG")/..
+
+  # make it fully qualified
+  M2_HOME=$(cd "$M2_HOME" && pwd)
+
+  cd "$saveddir"
+  # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=$(cygpath --unix "$M2_HOME")
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME="$( (
+      cd "$M2_HOME"
+      pwd
+    ))"
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME="$( (
+      cd "$JAVA_HOME"
+      pwd
+    ))"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  javaExecutable="$(which javac)"
+  if [ -n "$javaExecutable" ] && ! [ "$(expr \"$javaExecutable\" : '\([^ ]*\)')" = "no" ]; then
+    # readlink(1) is not available as standard on Solaris 10.
+    readLink=$(which readlink)
+    if [ ! $(expr "$readLink" : '\([^ ]*\)') = "no" ]; then
+      if $darwin; then
+        javaHome="$(dirname \"$javaExecutable\")"
+        javaExecutable="$(cd \"$javaHome\" && pwd -P)/javac"
+      else
+        javaExecutable="$(readlink -f \"$javaExecutable\")"
+      fi
+      javaHome="$(dirname \"$javaExecutable\")"
+      javaHome=$(expr "$javaHome" : '\(.*\)/bin')
+      JAVA_HOME="$javaHome"
+      export JAVA_HOME
+    fi
+  fi
+fi
+
+if [ -z "$JAVACMD" ]; then
+  if [ -n "$JAVA_HOME" ]; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ]; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+    fi
+  else
+    JAVACMD="$(which java)"
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ]; then
+  echo "Error: JAVA_HOME is not defined correctly." >&2
+  echo "  We cannot execute $JAVACMD" >&2
+  exit 1
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+  if [ -z "$1" ]; then
+    echo "Path not specified to find_maven_basedir"
+    return 1
+  fi
+
+  basedir="$1"
+  wdir="$1"
+  while [ "$wdir" != '/' ]; do
+    if [ -d "$wdir"/.mvn ]; then
+      basedir=$wdir
+      break
+    fi
+    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+    if [ -d "${wdir}" ]; then
+      wdir=$(
+        cd "$wdir/.."
+        pwd
+      )
+    fi
+    # end of workaround
+  done
+  echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    echo "$(tr -s '\n' ' ' <"$1")"
+  fi
+}
+
+BASE_DIR=$(find_maven_basedir "$(pwd)")
+if [ -z "$BASE_DIR" ]; then
+  exit 1
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+  if [ "$MVNW_VERBOSE" = true ]; then
+    echo "Found .mvn/wrapper/maven-wrapper.jar"
+  fi
+else
+  if [ "$MVNW_VERBOSE" = true ]; then
+    echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+  fi
+  if [ -n "$MVNW_REPOURL" ]; then
+    jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+  else
+    jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+  fi
+  while IFS="=" read key value; do
+    case "$key" in wrapperUrl)
+      jarUrl="$value"
+      break
+      ;;
+    esac
+  done <"$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+  if [ "$MVNW_VERBOSE" = true ]; then
+    echo "Downloading from: $jarUrl"
+  fi
+  wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+  if $cygwin; then
+    wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
+  fi
+
+  if command -v wget >/dev/null; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found wget ... using wget"
+    fi
+    if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+      wget "$jarUrl" -O "$wrapperJarPath"
+    else
+      wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+    fi
+  elif command -v curl >/dev/null; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found curl ... using curl"
+    fi
+    if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+      curl -o "$wrapperJarPath" "$jarUrl" -f
+    else
+      curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+    fi
+
+  else
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Falling back to using Java to download"
+    fi
+    javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+    # For Cygwin, switch paths to Windows format before running javac
+    if $cygwin; then
+      javaClass=$(cygpath --path --windows "$javaClass")
+    fi
+    if [ -e "$javaClass" ]; then
+      if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo " - Compiling MavenWrapperDownloader.java ..."
+        fi
+        # Compiling the Java class
+        ("$JAVA_HOME/bin/javac" "$javaClass")
+      fi
+      if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+        # Running the downloader
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo " - Running MavenWrapperDownloader.java ..."
+        fi
+        ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+      fi
+    fi
+  fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+  echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=$(cygpath --path --windows "$M2_HOME")
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
+  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+    MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

+ 182 - 0
mvnw.cmd

@@ -0,0 +1,182 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM     e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Found %WRAPPER_JAR%
+    )
+) else (
+    if not "%MVNW_REPOURL%" == "" (
+        SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %DOWNLOAD_URL%
+    )
+
+    powershell -Command "&{"^
+		"$webclient = new-object System.Net.WebClient;"^
+		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+		"}"^
+		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%

+ 156 - 0
pom.xml

@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.3.11.RELEASE</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>com.tsi.api</groupId>
+    <artifactId>tsi-node-dir</artifactId>
+    <version>0.0.1</version>
+    <name>tsi-node-dir</name>
+    <description>TSI Node Dir Application</description>
+
+    <packaging>jar</packaging>
+
+    <repositories>
+        <repository>
+            <id>oracle</id>
+            <url>http://maven.jahia.org/maven2</url>
+        </repository>
+    </repositories>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <!-- jar 배포용 -->
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+        <!--main 함수가 있는 class 경로-->
+        <start-class>com.tsi.api.server.TsiNodeDirApplication</start-class>
+        <webapp.lib>C://UTIC-2021//tsi-repository</webapp.lib>
+        <maven.test.skip>true</maven.test.skip>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.tsi</groupId>
+            <artifactId>tsi-common</artifactId>
+            <version>1.0</version>
+            <scope>system</scope>
+            <systemPath>${webapp.lib}/tsi-common.jar</systemPath>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jdbc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>2.1.3</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.bgee.log4jdbc-log4j2</groupId>
+            <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
+            <version>1.16</version>
+        </dependency>
+
+        <!-- FOR DATABASE: START -->
+        <dependency>
+            <groupId>com.oracle</groupId>
+            <artifactId>ojdbc7</artifactId>
+            <version>12.1.0.2</version>
+            <scope>system</scope>
+            <systemPath>${webapp.lib}/ojdbc7-12.1.0.2.jar</systemPath>
+        </dependency>
+
+        <dependency>
+            <groupId>tibero6</groupId>
+            <artifactId>tibero6-jdbc</artifactId>
+            <version>1.0.0</version>
+            <scope>system</scope>
+            <systemPath>${webapp.lib}/tibero6-jdbc-14.jar</systemPath>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mariadb.jdbc</groupId>
+            <artifactId>mariadb-java-client</artifactId>
+            <version>2.7.0</version>
+        </dependency>
+        <!-- FOR DATABASE: END -->
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <scope>runtime</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>net.sf.json-lib</groupId>
+            <artifactId>json-lib</artifactId>
+            <version>2.4</version>
+            <classifier>jdk15</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-tomcat</artifactId>
+        </dependency>
+
+        <!-- FOR UTIL: START -->
+        <dependency>
+            <groupId>com.github.dozermapper</groupId>
+            <artifactId>dozer-spring4</artifactId>
+            <version>6.5.0</version>
+        </dependency>
+        <!-- FOR UTIL: END -->
+
+        <!-- FOR JPA: START -->
+        <!--<dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>-->
+        <!-- FOR JPA: END -->
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 79 - 0
src/main/java/com/tsi/api/server/TsiNodeDirApplication.java

@@ -0,0 +1,79 @@
+package com.tsi.api.server;
+
+import com.tsi.api.server.mybatis.TsiDatabaseService;
+import com.tsi.app.common.app.AppUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.boot.Banner;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.event.ContextClosedEvent;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+@Slf4j
+@MapperScan(basePackageClasses = TsiNodeDirApplication.class)
+@SpringBootApplication
+@ComponentScan(basePackages = {"com.tsi.app.common", "com.tsi.api.server"})
+public class TsiNodeDirApplication implements CommandLineRunner, ApplicationListener<ContextClosedEvent>, InitializingBean, DisposableBean {
+
+    public static void main(String[] args) {
+        SpringApplication application = new SpringApplicationBuilder()
+                .sources(TsiNodeDirApplication.class)
+                .build();
+        application.setBannerMode(Banner.Mode.OFF);
+        application.run(args);
+    }
+
+    @Override
+    public void run(String... args) throws Exception {
+        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        log.info("");
+        log.info("************************************************************************************");
+        log.info("** startup: {}", sdfDate.format(new Date()));
+        log.info("************************************************************************************");
+
+        TsiDatabaseService tsiDatabaseService = (TsiDatabaseService) AppUtils.getBean(TsiDatabaseService.class);
+        tsiDatabaseService.loadNodeApp();
+        tsiDatabaseService.loadLinkApp();
+        tsiDatabaseService.makeNodeDir();
+
+/*
+        TsiAlarmManager.getInstance().getProcessStateVo().setProcessId(applicationName);
+        try {
+            TsiDatabaseService tsiDatabaseService = (TsiDatabaseService) AppUtils.getBean(TsiDatabaseService.class);
+            AlarmOccrVo alarm = new AlarmOccrVo(AbstractDbmsVo.DBMS_ALARM_OCCR_HS);
+            alarm.setAlarmCode(TsiAlarmConfigVo.SYS_00);
+            alarm.setAlarmTarget(applicationName);
+            alarm.setAlarmValue("Running");
+            tsiDatabaseService.insertAlarmOccrHs(alarm);
+            tsiDatabaseService.updateProcessState(0);
+        }
+        catch(Exception e) {
+        }
+*/
+    }
+
+    @Override
+    public void destroy() throws Exception {
+
+    }
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+
+    }
+
+    @Override
+    public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
+        SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        log.error("Application Terminated: {}, {}", sdfDate.format(new Date()), contextClosedEvent.toString());
+    }
+}

+ 62 - 0
src/main/java/com/tsi/api/server/mybatis/MybatisConfig.java

@@ -0,0 +1,62 @@
+package com.tsi.api.server.mybatis;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.annotation.PostConstruct;
+import javax.sql.DataSource;
+
+@Configuration
+@EnableTransactionManagement
+public class MybatisConfig {
+
+    @Value("${spring.datasource.mybatis.mapper-locations:classpath:mybatis/mapper/**/*.xml}")
+    String mapperLocations;
+
+    @PostConstruct
+    private void init() {
+    }
+
+    @Primary
+    @Bean(name="dataSource")
+    @ConfigurationProperties(prefix="spring.datasource.mybatis")
+    public DataSource dataSource() {
+        return DataSourceBuilder.create().build();
+        //return DataSourceBuilder.create().type(HikariDataSource.class).build();
+    }
+
+    @Primary
+    @Bean(name="sqlSessionFactory")
+    public SqlSessionFactory sqlSessionFactoryBean(@Autowired @Qualifier("dataSource") DataSource dataSource, ApplicationContext applicationContext)
+            throws Exception {
+        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
+        factoryBean.setDataSource(dataSource);
+        //factoryBean.setConfigLocation(applicationContext.getResource("classpath:mybatis/mapper/mybatis-config.xml"));
+        factoryBean.setMapperLocations(applicationContext.getResources(mapperLocations));
+        return factoryBean.getObject();
+    }
+
+    @Primary
+    @Bean(name="sqlSession")
+    public SqlSessionTemplate sqlSession(@Autowired @Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
+        return new SqlSessionTemplate(sqlSessionFactory);
+    }
+
+    @Primary
+    @Bean(name="transactionManager")
+    public DataSourceTransactionManager transactionManager(@Autowired @Qualifier("dataSource") DataSource dataSource) {
+        return new DataSourceTransactionManager(dataSource);
+    }
+}

+ 15 - 0
src/main/java/com/tsi/api/server/mybatis/TsiDatabaseMapper.java

@@ -0,0 +1,15 @@
+package com.tsi.api.server.mybatis;
+
+import com.tsi.api.server.mybatis.vo.LinkAppVo;
+import com.tsi.api.server.mybatis.vo.NodeAppVo;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+@Mapper
+public interface TsiDatabaseMapper {
+
+    List<NodeAppVo> getNodeApp();
+    List<LinkAppVo> getLinkApp();
+
+}

+ 89 - 0
src/main/java/com/tsi/api/server/mybatis/TsiDatabaseService.java

@@ -0,0 +1,89 @@
+package com.tsi.api.server.mybatis;
+
+import com.tsi.api.server.mybatis.vo.LinkAppVo;
+import com.tsi.api.server.mybatis.vo.NodeAppDirVo;
+import com.tsi.api.server.mybatis.vo.NodeAppVo;
+import com.tsi.api.server.repository.TsiNodeManager;
+import com.tsi.api.server.util.LocationUtils;
+import com.tsi.api.server.util.TsiDirection;
+import com.tsi.app.common.app.AppUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class TsiDatabaseService {
+
+    private TsiDatabaseMapper tsiDatabaseMapper;
+
+    public TsiDatabaseService() {
+    }
+
+    @PostConstruct
+    void init() {
+        log.info("TsiDatabaseService: init");
+        this.tsiDatabaseMapper = (TsiDatabaseMapper) AppUtils.getBean(TsiDatabaseMapper.class);
+/*
+        loadNodeApp();
+        loadLinkApp();
+*/
+    }
+
+    public void loadNodeApp() {
+        List<NodeAppVo> objLists = this.tsiDatabaseMapper.getNodeApp();
+        for (NodeAppVo obj : objLists) {
+            TsiNodeManager.getInstance().getNodeAppMap().put(obj.getNodeId(), obj);
+        }
+
+        log.info("loadNodeApp: {} EA.", TsiNodeManager.getInstance().getNodeAppMap().size());
+    }
+
+
+    public void loadLinkApp() {
+        List<LinkAppVo> objLists = this.tsiDatabaseMapper.getLinkApp();
+        long key = 0;
+        for (LinkAppVo obj : objLists) {
+            TsiNodeManager.getInstance().getLinkAppMap().put(key++, obj);
+        }
+
+        log.info("loadLinkApp: {} EA.", TsiNodeManager.getInstance().getLinkAppMap().size());
+    }
+
+    public void makeNodeDir() {
+
+        TsiDirection direction = new TsiDirection();
+
+        int bearing;
+        int dirCode;
+        for (Map.Entry<Long, LinkAppVo> obj : TsiNodeManager.getInstance().getLinkAppMap().entrySet()) {
+            NodeAppVo stNode = TsiNodeManager.getInstance().getNodeAppMap().get(obj.getValue().getStNodeId());
+            NodeAppVo edNode = TsiNodeManager.getInstance().getNodeAppMap().get(obj.getValue().getEdNodeId());
+            if (stNode == null || edNode == null) {
+                log.error("makeNodeDir: not found node: {}, {}, stNode: {}, edNode: {}", obj.getValue().getStNodeId(), obj.getValue().getEdNodeId(), stNode, edNode);
+                continue;
+            }
+
+            bearing = LocationUtils.getBearing(stNode.getLatitude(), stNode.getLongitude(), edNode.getLatitude(), edNode.getLongitude());
+            dirCode = direction.getCode(bearing);
+            NodeAppDirVo appDir = TsiNodeManager.getInstance().getNodeAppDirMap().get(edNode.getNodeId());
+            if (appDir == null) {
+                appDir = new NodeAppDirVo();
+                appDir.setNodeId(edNode.getNodeId());
+                appDir.setDirCode(String.valueOf(stNode.getNodeId()) + "," + String.valueOf(dirCode));
+                TsiNodeManager.getInstance().getNodeAppDirMap().put(appDir.getNodeId(), appDir);
+            } else {
+                String stringDirCode = appDir.getDirCode() + "|" + String.valueOf(stNode.getNodeId()) + "," + String.valueOf(dirCode);
+                appDir.setDirCode(stringDirCode);
+            }
+            //log.info("{} -> {}, {}", stNode.getNodeName(), edNode.getNodeName(), dirCode);
+        }
+
+        for (Map.Entry<Long, NodeAppDirVo> obj : TsiNodeManager.getInstance().getNodeAppDirMap().entrySet()) {
+            log.info("insert into tb_tsc_node_dir(node_id, dir_code) values ({}, '{}');", obj.getValue().getNodeId(), obj.getValue().getDirCode());
+        }
+    }
+}

+ 10 - 0
src/main/java/com/tsi/api/server/mybatis/vo/LinkAppVo.java

@@ -0,0 +1,10 @@
+package com.tsi.api.server.mybatis.vo;
+
+import lombok.Data;
+
+@Data
+public class LinkAppVo {
+    private long stNodeId;
+    private long edNodeId;
+    private int dist;
+}

+ 9 - 0
src/main/java/com/tsi/api/server/mybatis/vo/NodeAppDirVo.java

@@ -0,0 +1,9 @@
+package com.tsi.api.server.mybatis.vo;
+
+import lombok.Data;
+
+@Data
+public class NodeAppDirVo {
+    private long nodeId;
+    private String dirCode;
+}

+ 13 - 0
src/main/java/com/tsi/api/server/mybatis/vo/NodeAppVo.java

@@ -0,0 +1,13 @@
+package com.tsi.api.server.mybatis.vo;
+
+import lombok.Data;
+
+@Data
+public class NodeAppVo {
+    private long nodeId;
+    private String nodeName;
+    private double latitude;
+    private double longitude;
+    private int nodeType;
+    private String useType;
+}

+ 45 - 0
src/main/java/com/tsi/api/server/repository/TsiNodeManager.java

@@ -0,0 +1,45 @@
+package com.tsi.api.server.repository;
+
+import com.tsi.api.server.mybatis.vo.LinkAppVo;
+import com.tsi.api.server.mybatis.vo.NodeAppDirVo;
+import com.tsi.api.server.mybatis.vo.NodeAppVo;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+@Slf4j
+public class TsiNodeManager {
+
+    private static TsiNodeManager _instance = null;
+
+    public static TsiNodeManager getInstance() {
+        if (_instance == null) {
+            synchronized (TsiNodeManager.class) {
+                if (_instance == null)
+                    _instance = new TsiNodeManager();
+            }
+        }
+        return _instance;
+    }
+
+    private TsiNodeManager() {
+        this.nodeAppMap = new ConcurrentHashMap<>();
+        this.linkAppMap = new ConcurrentHashMap<>();
+        this.nodeAppDirMap = new ConcurrentHashMap<>();
+    }
+
+    private ConcurrentHashMap<Long, NodeAppVo> nodeAppMap;
+    private ConcurrentHashMap<Long, LinkAppVo> linkAppMap;
+    private ConcurrentHashMap<Long, NodeAppDirVo> nodeAppDirMap;
+
+
+    public ConcurrentHashMap<Long, NodeAppVo> getNodeAppMap() {
+        return this.nodeAppMap;
+    }
+    public ConcurrentHashMap<Long, LinkAppVo> getLinkAppMap() {
+        return this.linkAppMap;
+    }
+    public ConcurrentHashMap<Long, NodeAppDirVo> getNodeAppDirMap() {
+        return this.nodeAppDirMap;
+    }
+}

+ 36 - 0
src/main/java/com/tsi/api/server/util/ApiUtils.java

@@ -0,0 +1,36 @@
+package com.tsi.api.server.util;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class ApiUtils {
+
+    public static String getRemoteIP(HttpServletRequest request) {
+        if (request == null) {
+            return "";
+        }
+
+        String ipAddr = request.getHeader("X-FORWARDED-FOR");
+
+        // proxy 환경일 경우
+        if (ipAddr == null || ipAddr.length() == 0) {
+            ipAddr = request.getHeader("Proxy-Client-IP");
+        }
+
+        // 웹로직 서버일 경우
+        if (ipAddr == null || ipAddr.length() == 0) {
+            ipAddr = request.getHeader("WL-Proxy-Client-IP");
+        }
+
+        // 기타
+        if (ipAddr == null || ipAddr.length() == 0) {
+            ipAddr = request.getRemoteAddr() ;
+        }
+
+        //-Djava.net.preferIPv4Stack=true
+        if (ipAddr.equals("0:0:0:0:0:0:0:1"))   //==> ipv6 <== default
+        {
+            ipAddr = "127.0.0.1";   //==> localhost
+        }
+        return ipAddr;
+    }
+}

+ 101 - 0
src/main/java/com/tsi/api/server/util/LocationUtils.java

@@ -0,0 +1,101 @@
+package com.tsi.api.server.util;
+
+import java.text.DecimalFormat;
+
+public class LocationUtils {
+    /**
+     * 두 좌표 거리 구하기
+     * @param latitude1 Start latitude
+     * @param longitude1 Start longitude
+     * @param latitude2 End latitude
+     * @param longitude2 End longitude
+     * @return Distance(m)
+     */
+    public static double geoDistance(double latitude1, double longitude1, double latitude2, double longitude2) {
+
+        DecimalFormat df = new DecimalFormat("#.#####");
+
+        if ((latitude1 == latitude2) && (longitude1 == longitude2)) {
+            return 0;
+        } else {
+            double theta = longitude1 - longitude2;
+            double distance = Math.sin(Math.toRadians(latitude1)) * Math.sin(Math.toRadians(latitude2)) +
+                    Math.cos(Math.toRadians(latitude1)) * Math.cos(Math.toRadians(latitude2)) * Math.cos(Math.toRadians(theta));
+            distance = Math.acos(distance);
+            distance = Math.toDegrees(distance);
+            distance = distance * 60 * 1.1515;
+            distance = distance * 1.609344;
+
+            //distance --> 0보다 클 경우
+            if (0 < distance) {
+                distance = Double.valueOf(df.format(distance));    //소숫점 다섯째 자리에서 반올림
+
+                // distance --> 0일 경우
+            } else {
+                distance = 0;
+            }
+
+            distance = distance * 1000; //km --> m으로 변환
+
+            return distance;
+        }
+
+    }
+
+    /**
+     * 두 좌표 방위각 구하기
+     * @param latitude1 Start latitude
+     * @param longitude1 Start longitude
+     * @param latitude2 End latitude
+     * @param longitude2 End longitude
+     * @return bearing
+     */
+    public static int getBearing(double latitude1, double longitude1, double latitude2, double longitude2) {
+        // 현재 위치 : 위도나 경도는 지구 중심을 기반으로 하는 각도이기 때문에 라디안 각도로 변환한다.
+        double Cur_Lat_radian = latitude1 * (Math.PI / 180);
+        double Cur_Lon_radian = longitude1 * (Math.PI / 180);
+
+        // 목표 위치 : 위도나 경도는 지구 중심을 기반으로 하는 각도이기 때문에 라디안 각도로 변환한다.
+        double Dest_Lat_radian = latitude2 * (Math.PI / 180);
+        double Dest_Lon_radian = longitude2 * (Math.PI / 180);
+
+        // radian distance
+        double radian_distance = 0;
+        radian_distance = Math.acos(Math.sin(Cur_Lat_radian) * Math.sin(Dest_Lat_radian)
+                + Math.cos(Cur_Lat_radian) * Math.cos(Dest_Lat_radian) * Math.cos(Cur_Lon_radian - Dest_Lon_radian));
+
+        // 목적지 이동 방향을 구한다.(현재 좌표에서 다음 좌표로 이동하기 위해서는 방향을 설정해야 한다. 라디안값이다.
+        double radian_bearing = Math.acos((Math.sin(Dest_Lat_radian) - Math.sin(Cur_Lat_radian)
+                * Math.cos(radian_distance)) / (Math.cos(Cur_Lat_radian) * Math.sin(radian_distance)));// acos의 인수로 주어지는 x는 360분법의 각도가 아닌 radian(호도)값이다.
+
+        double true_bearing = 0;
+        if (Math.sin(Dest_Lon_radian - Cur_Lon_radian) < 0) {
+            true_bearing = radian_bearing * (180 / Math.PI);
+            true_bearing = 360 - true_bearing;
+        } else {
+            true_bearing = radian_bearing * (180 / Math.PI);
+        }
+
+        return (int) true_bearing;
+    }
+
+    /**
+     * 특정 좌표에서 방위각, 거리를 가지고 원하는 좌표 값 획득
+     * @param latitude latitude
+     * @param longitude longitude
+     * @param direction_degree direction
+     * @param length_degree length
+     * @return double[2] location = {longitude, latitude}
+     */
+    public static double[] geoMove(double latitude, double longitude, double direction_degree, double length_degree) {
+        double[] location = new double[2];
+
+        double x = longitude + length_degree * Math.cos(direction_degree * Math.PI / 180);
+        double y = latitude + length_degree * Math.sin(direction_degree * Math.PI / 180);
+
+        location[0] = x;
+        location[1] = y;
+
+        return location;
+    }
+}

+ 85 - 0
src/main/java/com/tsi/api/server/util/TsiDirection.java

@@ -0,0 +1,85 @@
+package com.tsi.api.server.util;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+public class TsiDirection {
+
+    private ConcurrentHashMap<Integer, String> directionMap = new ConcurrentHashMap<Integer, String>();
+    private ConcurrentHashMap<String, Integer> directionNameMap = new ConcurrentHashMap<String, Integer>();
+
+    private ConcurrentHashMap<Integer, Integer> directionAngle = new ConcurrentHashMap<Integer, Integer>();
+
+    public TsiDirection() {
+        this.directionMap.put(10, "북(10)");
+        this.directionMap.put(20, "동(20)");
+        this.directionMap.put(30, "남(30)");
+        this.directionMap.put(40, "서(40)");
+        this.directionMap.put(50, "북동(50)");
+        this.directionMap.put(60, "남동(60)");
+        this.directionMap.put(70, "남서(70)");
+        this.directionMap.put(80, "북서(80)");
+
+        this.directionNameMap.put("북(10)", 10);
+        this.directionNameMap.put("동(20)", 20);
+        this.directionNameMap.put("남(30)", 30);
+        this.directionNameMap.put("서(40)", 40);
+        this.directionNameMap.put("북동(50)", 50);
+        this.directionNameMap.put("남동(60)", 60);
+        this.directionNameMap.put("남서(70)", 70);
+        this.directionNameMap.put("북서(80)", 80);
+
+        int directionCode = 0;
+        for (int ii = 0; ii < 360; ii++) {
+            if      (ii >  22 && ii <=  67) directionCode = 70;
+            else if (ii >  67 && ii <= 112) directionCode = 40;
+            else if (ii > 112 && ii <= 157) directionCode = 80;
+            else if (ii > 157 && ii <= 202) directionCode = 10;
+            else if (ii > 202 && ii <= 247) directionCode = 50;
+            else if (ii > 247 && ii <= 292) directionCode = 20;
+            else if (ii > 292 && ii <= 337) directionCode = 60;
+            else directionCode = 30;
+
+            this.directionAngle.put(ii, directionCode);
+        }
+    }
+    /*
+    public static int getDirectionCode(double bearing) {
+
+        if (bearing >= 22.5 && bearing < 67.5) return 70;
+        if (bearing >= 67.5 && bearing < 112.5) return 40;
+        if (bearing >= 112.5 && bearing < 157.5) return 80;
+        if (bearing >= 157.5 && bearing < 202.5) return 10;
+        if (bearing >= 202.5 && bearing < 247.5) return 50;
+        if (bearing >= 247.5 && bearing < 292.5) return 20;
+        if (bearing >= 292.5 && bearing < 337.5) return 60;
+        return 30;
+    }
+
+    public static int getRunDirectionCode(double bearing) {
+
+        if (bearing >= 22.5 && bearing < 67.5) return 50;
+        if (bearing >= 67.5 && bearing < 112.5) return 20;
+        if (bearing >= 112.5 && bearing < 157.5) return 60;
+        if (bearing >= 157.5 && bearing < 202.5) return 30;
+        if (bearing >= 202.5 && bearing < 247.5) return 70;
+        if (bearing >= 247.5 && bearing < 292.5) return 40;
+        if (bearing >= 292.5 && bearing < 337.5) return 80;
+        return 10;
+    }
+    */
+
+    public int getNameCode(String directionName) {
+        Integer direction = this.directionNameMap.get(directionName);
+        return (direction != null) ? direction : 99;
+    }
+
+    public String getName(int direction) {
+        String directionName = this.directionMap.get(direction);
+        return (directionName != null) ? directionName :  "(" + direction + ")";
+    }
+
+    public int getCode(double bearing) {
+        Integer directionCode = this.directionAngle.get((int)bearing);
+        return (directionCode != null) ? directionCode :  10;
+    }
+}

+ 36 - 0
src/main/resources/application.yml

@@ -0,0 +1,36 @@
+spring:
+  application:
+    name: tsi-node-dir
+  main:
+    web-application-type: none
+
+  datasource:
+    mybatis:
+      platform: mariadb
+      driver-class-name: oracle.jdbc.OracleDriver
+      username: ssip
+      password: ssip
+      jpool-name: hikari-cp
+      jmaximum-pool-size: 30
+      jminimum-idle: 2
+
+---
+spring:
+  profiles: wonju
+  datasource:
+    mybatis:
+      jdbc-url: jdbc:oracle:thin:@127.0.0.1:1521:HANTE
+
+---
+spring:
+  profiles: seoul
+  datasource:
+    mybatis:
+      jdbc-url: jdbc:oracle:thin:@127.0.0.1:1521:HANTE
+
+---
+spring:
+  profiles: dev
+  datasource:
+    mybatis:
+      jdbc-url: jdbc:oracle:thin:@127.0.0.1:1521:HANTE

+ 9 - 0
src/main/resources/banner.txt

@@ -0,0 +1,9 @@
+  _____   ____    ___        _      ____    ____      ____
+ |_   _| / ___|  |_ _|      / \    |  _ \  |  _ \    / ___|    ___   _ __  __   __   ___   _ __
+   | |   \___ \   | |      / _ \   | |_) | | |_) |   \___ \   / _ \ | '__| \ \ / /  / _ \ | '__|
+   | |    ___) |  | |     / ___ \  |  __/  |  __/     ___) | |  __/ | |     \ V /  |  __/ | |
+   |_|   |____/  |___|   /_/   \_\ |_|     |_|       |____/   \___| |_|      \_/    \___| |_|
+
+spring-boot.version: ${spring-boot.version}
+application.version: ${application.version}
+  application.title: ${application.title}

+ 87 - 0
src/main/resources/logback-spring.xml

@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="60 seconds">
+    <shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
+
+    <property name="PROJECT_NAME"    value="tsi-node-dir"/>
+    <property name="ROOT_LOG_LEVEL"  value="DEBUG"/>
+    <property name="LOG_CHARSET"     value="UTF-8" />
+    <property name="LOG_PATH"        value="${user.dir}/logs/${PROJECT_NAME}/"/>
+    <property name="LOG_BACKUP_PATH" value="${user.dir}/logs/${PROJECT_NAME}/backup/"/>
+
+    <property name="LOG_FILE_NAME"             value="${PROJECT_NAME}.log"/>
+    <property name="LOG_FILE_NAME_ERROR"       value="${PROJECT_NAME}.err.log"/>
+    <property name="LOG_FILE_NAME_SCHEDULE"    value="schedule.log"/>
+    <property name="LOG_FILE_NAME_PATTERN"     value="%d{yyyyMMdd}_%i.log.gz"/>
+
+    <property name="MAX_FILESIZE" value="500MB"/>
+    <property name="MAX_HISTORY"  value="30"/>
+    <property name="LOG_PATTERN_FILE"        value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
+    <property name="LOG_PATTERN_ERROR"       value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%30t] [%5level] %42logger{35}.%-20M ${PID:-} %msg%n"/>
+    <property name="LOG_PATTERN_SQL"         value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %msg%n"/>
+
+    <property name="LOG_PATTERN_CONSOLE" value="[%d{HH:mm:ss.SSS}] %highlight([%5level]) %highlight(${PID:-}): %cyan(%msg) %n"/>
+
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <withJansi>true</withJansi>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <charset>${LOG_CHARSET}</charset>
+            <pattern>${LOG_PATTERN_CONSOLE}</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="FILE_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_PATH}${LOG_FILE_NAME}</file>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <charset>${LOG_CHARSET}</charset>
+            <pattern>${LOG_PATTERN_FILE}</pattern>
+        </encoder>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
+            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
+            <maxHistory>${MAX_HISTORY}</maxHistory>
+        </rollingPolicy>
+    </appender>
+
+    <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>error</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <file>${LOG_PATH}${LOG_FILE_NAME_ERROR}</file>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <charset>${LOG_CHARSET}</charset>
+            <pattern>${LOG_PATTERN_ERROR}</pattern>
+        </encoder>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME_ERROR}.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
+            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
+            <maxHistory>${MAX_HISTORY}</maxHistory>
+        </rollingPolicy>
+    </appender>
+
+    <root level="INFO">
+        <appender-ref ref="CONSOLE"/>
+        <appender-ref ref="FILE_LOG"/>
+        <appender-ref ref="FILE_ERROR"/>
+    </root>
+
+    <appender name="FILE_SCHEDULE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_PATH}${LOG_FILE_NAME_SCHEDULE}</file>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <charset>${LOG_CHARSET}</charset>
+            <pattern>${LOG_PATTERN_FILE}</pattern>
+        </encoder>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_BACKUP_PATH}${LOG_FILE_NAME_SCHEDULE}.${LOG_FILE_NAME_PATTERN}</fileNamePattern>
+            <maxFileSize>${MAX_FILESIZE}</maxFileSize>
+            <maxHistory>${MAX_HISTORY}</maxHistory>
+        </rollingPolicy>
+    </appender>
+
+    <logger name="com.tsi.api.server.scheduler" level="INFO" additivity="false">
+        <appender-ref ref="FILE_SCHEDULE"/>
+        <appender-ref ref="FILE_ERROR"/>
+    </logger>
+
+</configuration>

+ 28 - 0
src/main/resources/mybatis/mapper/tsi-database.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.tsi.api.server.mybatis.TsiDatabaseMapper">
+
+    <select id="getNodeApp" parameterType="java.util.HashMap" resultType="com.tsi.api.server.mybatis.vo.NodeAppVo">
+        <![CDATA[
+        select a.node_id as nodeId,
+               a.node_name as nodeName,
+               a.latitude as latitude,
+               a.longitude as longitude,
+               a.node_type as nodeType,
+               a.use_type as useType
+        from TB_NODE_APP a
+        ]]>
+    </select>
+
+    <select id="getLinkApp" parameterType="java.util.HashMap" resultType="com.tsi.api.server.mybatis.vo.LinkAppVo">
+        <![CDATA[
+        select a.st_node_id as stNodeId,
+               a.ed_node_id as edNodeId,
+               max(a.length) as dist
+          from TB_NODE_APP_LINK a
+         group by a.st_node_id, a.ed_node_id
+        ]]>
+    </select>
+
+</mapper>

+ 21 - 0
src/main/resources/mybatis/mybatis-config.xml

@@ -0,0 +1,21 @@
+<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "HTTP://mybatis.org/dtd/mybatis-3-config.dtd">
+<configuration>
+	<settings>
+		<setting name="aggressiveLazyLoading" value="false"/>
+		<setting name="jdbcTypeForNull" value="NULL"/>
+		<setting name="cacheEnabled" value="true"/>
+		<setting name="lazyLoadingEnabled" value="false"/>
+		<setting name="multipleResultSetsEnabled" value="true"/>
+		<setting name="useColumnLabel" value="true"/>
+		<setting name="useGeneratedKeys" value="false"/>
+		<setting name="defaultExecutorType" value="REUSE"/>
+		<setting name="defaultStatementTimeout" value="25000"/>
+		<setting name="mapUnderscoreToCamelCase" value="true"/>
+	</settings>
+    
+	<typeAliases>
+	</typeAliases>
+	
+	<typeHandlers>
+	</typeHandlers>
+</configuration>