diff --git a/pom.xml b/pom.xml
index d760ab36..856bb154 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,22 +36,26 @@
messageSource:
diff --git a/src/main/java/cokr/xit/base/boot/DatasourceConfig2.java b/src/main/java/cokr/xit/custom/boot/DatasourceConfig2.java
similarity index 99%
rename from src/main/java/cokr/xit/base/boot/DatasourceConfig2.java
rename to src/main/java/cokr/xit/custom/boot/DatasourceConfig2.java
index 1e2f0d9e..af7cead0 100644
--- a/src/main/java/cokr/xit/base/boot/DatasourceConfig2.java
+++ b/src/main/java/cokr/xit/custom/boot/DatasourceConfig2.java
@@ -1,4 +1,4 @@
-package cokr.xit.base.boot;
+package cokr.xit.custom.boot;
import javax.sql.DataSource;
diff --git a/src/main/java/cokr/xit/base/boot/MvcConfig4.java b/src/main/java/cokr/xit/custom/boot/MvcConfig4.java
similarity index 95%
rename from src/main/java/cokr/xit/base/boot/MvcConfig4.java
rename to src/main/java/cokr/xit/custom/boot/MvcConfig4.java
index efb19561..bb0b9e12 100644
--- a/src/main/java/cokr/xit/base/boot/MvcConfig4.java
+++ b/src/main/java/cokr/xit/custom/boot/MvcConfig4.java
@@ -1,4 +1,4 @@
-package cokr.xit.base.boot;
+package cokr.xit.custom.boot;
import javax.annotation.Resource;
@@ -15,19 +15,18 @@ import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import com.fasterxml.jackson.databind.ObjectMapper;
-import cokr.xit.foundation.boot.StaticResourceConfig;
import cokr.xit.foundation.web.AccessInitializer;
@Configuration
public class MvcConfig4 implements WebMvcConfigurer {
protected static String[] URL_PATTERNS = {"/lvis/**/*"};
@Resource(name = "staticResource")
- private StaticResourceConfig staticResource;
+ private StaticResourceConfig2 staticResource;
/**AccessInitializer를 반환한다.
* @return AccessInitializer
*/
- @Bean
+ @Bean(name="accessInitializer2")
public AccessInitializer accessInitializer() {
return new AccessInitializer();
}
diff --git a/src/main/java/cokr/xit/base/boot/ServletConfig2.java b/src/main/java/cokr/xit/custom/boot/ServletConfig2.java
similarity index 95%
rename from src/main/java/cokr/xit/base/boot/ServletConfig2.java
rename to src/main/java/cokr/xit/custom/boot/ServletConfig2.java
index 55e46fe5..6da023c1 100644
--- a/src/main/java/cokr/xit/base/boot/ServletConfig2.java
+++ b/src/main/java/cokr/xit/custom/boot/ServletConfig2.java
@@ -1,4 +1,4 @@
-package cokr.xit.base.boot;
+package cokr.xit.custom.boot;
import javax.annotation.Resource;
@@ -13,13 +13,11 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CharacterEncodingFilter;
-import cokr.xit.foundation.boot.StaticResourceConfig;
-
@Configuration
public class ServletConfig2 {
protected static String[] URL_PATTERNS = {"/","*.do"};
@Resource(name = "staticResource")
- private StaticResourceConfig staticResource;
+ private StaticResourceConfig2 staticResource;
/**CharacterEncodingFilter를 등록한다.
* @return FilterRegistrationBean
diff --git a/src/main/java/cokr/xit/custom/boot/StandAloneApplication2.java b/src/main/java/cokr/xit/custom/boot/StandAloneApplication2.java
new file mode 100644
index 00000000..eeb1ae29
--- /dev/null
+++ b/src/main/java/cokr/xit/custom/boot/StandAloneApplication2.java
@@ -0,0 +1,37 @@
+package cokr.xit.custom.boot;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.WebApplicationType;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
+import org.springframework.test.context.ContextConfiguration;
+
+/**Spring Boot에서 xit-foundation.jar를 사용하는 stand-alone 애플리케이션의 베이스 클래스
+ * 설정 파일을 추가하여 사용하는 경우 설정 파일은
+ *
- 클래스패스의 spring 폴더 아래에 있어야 하고
+ * - 이름은 'context-'로 시작하는 xml이어야 한다
+ * - 즉 classpath*:spring/context-*.xml 경로에 해당해야 한다.
+ *
+ * @author mjkhan
+ */
+@SpringBootApplication(exclude = {
+ WebMvcAutoConfiguration.class
+})
+@ImportAutoConfiguration({
+ CommonConfig2.class,
+ DatasourceConfig2.class,
+ TransactionConfig2.class,
+})
+@ContextConfiguration("classpath:spring/context-*.xml")
+public class StandAloneApplication2 implements CommandLineRunner {
+ @Override
+ public void run(String... args) throws Exception {}
+
+ protected static void start(Class> klass, String... args) {
+ SpringApplication app = new SpringApplication(klass);
+ app.setWebApplicationType(WebApplicationType.NONE);
+ app.run(args);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/cokr/xit/custom/boot/StaticResourceConfig2.java b/src/main/java/cokr/xit/custom/boot/StaticResourceConfig2.java
new file mode 100644
index 00000000..3c039304
--- /dev/null
+++ b/src/main/java/cokr/xit/custom/boot/StaticResourceConfig2.java
@@ -0,0 +1,55 @@
+package cokr.xit.custom.boot;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Predicate;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+import cokr.xit.foundation.Assert;
+import cokr.xit.foundation.data.StringMap;
+
+@Configuration("staticResource")
+public class StaticResourceConfig2 {
+ @Value("${spring.mvc.static-path-pattern}")
+ private String staticURLs;
+ @Value("${spring.web.resources.static-locations}")
+ private String staticLocations;
+
+ public Map getMappings() {
+ if (Assert.isEmpty(staticURLs) && Assert.isEmpty(staticLocations))
+ return Collections.emptyMap();
+
+ List
+ urls = Arrays.asList(staticURLs.split(",")),
+ locations = Arrays.asList(staticLocations.split(","));
+ if (urls.size() != locations.size())
+ throw new RuntimeException("URLs and locations do not match in size for static resources");
+
+ StringMap resMap = new StringMap<>();
+ for (int i = 0; i < urls.size(); ++i) {
+ String url = urls.get(i),
+ location = locations.get(i);
+ resMap.put(url.trim(), location.trim());
+ }
+
+ return resMap;
+ }
+
+ public String[] getURLs(Predicate> filter) {
+ Predicate> test = filter != null ? filter : entry -> true;
+ List urls = getMappings().entrySet().stream()
+ .filter(test)
+ .map(entry -> entry.getKey())
+ .toList();
+ return urls.toArray(new String[urls.size()]);
+ }
+
+ public String[] getLocations() {
+ List locations = getMappings().values().stream().toList();
+ return locations.toArray(new String[locations.size()]);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/cokr/xit/base/boot/TransactionConfig2.java b/src/main/java/cokr/xit/custom/boot/TransactionConfig2.java
similarity index 98%
rename from src/main/java/cokr/xit/base/boot/TransactionConfig2.java
rename to src/main/java/cokr/xit/custom/boot/TransactionConfig2.java
index de48f4d2..f0092b60 100644
--- a/src/main/java/cokr/xit/base/boot/TransactionConfig2.java
+++ b/src/main/java/cokr/xit/custom/boot/TransactionConfig2.java
@@ -1,4 +1,4 @@
-package cokr.xit.base.boot;
+package cokr.xit.custom.boot;
import java.util.List;
import java.util.Map;
diff --git a/src/main/java/cokr/xit/base/boot/WebServiceConfig.java b/src/main/java/cokr/xit/custom/boot/WebServiceConfig.java
similarity index 97%
rename from src/main/java/cokr/xit/base/boot/WebServiceConfig.java
rename to src/main/java/cokr/xit/custom/boot/WebServiceConfig.java
index 2778ceb7..738db4ab 100644
--- a/src/main/java/cokr/xit/base/boot/WebServiceConfig.java
+++ b/src/main/java/cokr/xit/custom/boot/WebServiceConfig.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package cokr.xit.base.boot;
+package cokr.xit.custom.boot;
import javax.xml.ws.Endpoint;
diff --git a/src/main/java/cokr/xit/base/boot/XitBaseApplication2.java b/src/main/java/cokr/xit/custom/boot/XitBaseApplication2.java
similarity index 94%
rename from src/main/java/cokr/xit/base/boot/XitBaseApplication2.java
rename to src/main/java/cokr/xit/custom/boot/XitBaseApplication2.java
index c6de43e2..e959274c 100644
--- a/src/main/java/cokr/xit/base/boot/XitBaseApplication2.java
+++ b/src/main/java/cokr/xit/custom/boot/XitBaseApplication2.java
@@ -1,4 +1,4 @@
-package cokr.xit.base.boot;
+package cokr.xit.custom.boot;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
diff --git a/src/main/java/cokr/xit/custom/boot/Yml2.java b/src/main/java/cokr/xit/custom/boot/Yml2.java
new file mode 100644
index 00000000..96f4a438
--- /dev/null
+++ b/src/main/java/cokr/xit/custom/boot/Yml2.java
@@ -0,0 +1,130 @@
+package cokr.xit.custom.boot;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.springframework.boot.env.YamlPropertySourceLoader;
+import org.springframework.core.env.PropertySource;
+import org.springframework.core.io.ClassPathResource;
+
+import cokr.xit.foundation.Assert;
+
+/**yml 파일 내용을 프로퍼티 형식으로 읽기를 지원하는 유틸리티.
+ *
+ * @author mjkhan
+ */
+public class Yml2 {
+ private Map source;
+
+ /**새 Yml을 생성한다.
+ * @param rootName 프로퍼티 소스의 루트 이름
+ * @param path 클래스패스에서 yml 파일의 경로
+ */
+ public Yml2(String rootName, String path) {
+ load(rootName, path);
+ }
+
+ /**지정하는 yml 파일의 프로퍼티들을 읽어들인다.
+ * @param rootName 프로퍼티 소스의 루트 이름
+ * @param path 클래스패스에서 yml 파일의 경로
+ * @return 현재 Yml
+ */
+ public Yml2 load(String rootName, String path) {
+ source = null;
+ try {
+ List> sources = new YamlPropertySourceLoader()
+ .load(rootName, new ClassPathResource(path));
+ if (!sources.isEmpty())
+ source = (Map)sources.get(0).getSource();
+ return this;
+ } catch (Exception e) {
+ throw Assert.runtimeException(e);
+ }
+ }
+
+ /**지정하는 프로퍼티(아래 참고)의 값을 반환한다.
+ * @param key 키. 프로퍼티 이름
+ * spring:
+ * application:
+ * name: my-application
+ *
+ * @return 지정하는 키의 프로퍼티 값
+ */
+ public String getValue(String key) {
+ if (source == null) return "";
+
+ Object obj = source.get(key);
+ return obj != null ? obj.toString() : "";
+ }
+
+ /**지정하는 문자열로 시작하는 프로퍼티(아래 참고) 값들을 반환한다.
+ * list:
+ * - item-0
+ * - item-2
+ * - item-3
+ * @param prefix 프로퍼티 접두어
+ * @return 지정하는 문자열로 시작하는 프로퍼티 값
+ */
+ public List getValues(String prefix) {
+ if (source == null) return Collections.emptyList();
+
+ return getPrefixed(prefix).stream()
+ .map(entry -> entry.getValue().toString())
+ .collect(Collectors.toList());
+ }
+
+ private List> getPrefixed(String prefix) {
+ return source.entrySet().stream()
+ .filter(entry -> entry.getKey().startsWith(prefix))
+ .collect(Collectors.toList());
+ }
+
+ /**지정하는 문자열로 시작하는 프로퍼티(아래 참고) 값들을 Map으로 반환한다.
+ * parent:
+ * - property-0: value-0
+ * - property-1: value-1
+ * - property-2: value-2
+ * @param prefix 프로퍼티 접두어
+ * @return 지정하는 문자열로 시작하는 프로퍼티로 된 Map
+ */
+ public Map getMap(String prefix) {
+ if (source == null) return Collections.emptyMap();
+
+ LinkedHashMap map = new LinkedHashMap<>();
+ getPrefixed(prefix).stream().forEach(entry -> putTo(map, entry));
+
+ return map;
+ }
+
+ private void putTo(LinkedHashMap map, Map.Entry entry) {
+ String key = entry.getKey();
+ key = key.substring(key.lastIndexOf(".") + 1);
+ String val = entry.getValue().toString();
+ map.put(key, val);
+ }
+
+ /**지정하는 문자열로 시작하는 프로퍼티들(아래 참고)을 Map 목록으로 반환한다.
+ * parent:
+ * - property-0: value-0.0
+ * property-1: value-0.1
+ * - property-0: value-1.0
+ * property-1: value-1.1
+ * @param prefix 프로퍼티 접두어
+ * @return 지정하는 문자열로 시작하는 프로퍼티들의 Map 목록
+ */
+ public List