diff --git a/2025-03/spring-05-springBoot/.gitignore b/2025-03/spring-05-springBoot/.gitignore new file mode 100644 index 00000000..e62c33c2 --- /dev/null +++ b/2025-03/spring-05-springBoot/.gitignore @@ -0,0 +1,4 @@ +.idea/ +*.iml + +target/ diff --git a/2025-03/spring-05-springBoot/greeting-app/.gitignore b/2025-03/spring-05-springBoot/greeting-app/.gitignore new file mode 100644 index 00000000..549e00a2 --- /dev/null +++ b/2025-03/spring-05-springBoot/greeting-app/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.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/ diff --git a/2025-03/spring-05-springBoot/greeting-app/pom.xml b/2025-03/spring-05-springBoot/greeting-app/pom.xml new file mode 100644 index 00000000..a26e65ab --- /dev/null +++ b/2025-03/spring-05-springBoot/greeting-app/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.2 + + + + ru.otus + greeting-app + 0.0.1-SNAPSHOT + greeting-app + Spring Boot project demo + + + 17 + 17 + 17 + UTF-8 + UTF-8 + 0.0.1-SNAPSHOT + + + + + + org.springframework.boot + spring-boot-starter + + + + ru.otus + io-starter + ${io.starter.version} + + + + org.projectlombok + lombok + true + ${lombok.version} + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/2025-03/spring-05-springBoot/greeting-app/src/main/java/ru/otus/greetingapp/GreetingAppApplication.java b/2025-03/spring-05-springBoot/greeting-app/src/main/java/ru/otus/greetingapp/GreetingAppApplication.java new file mode 100644 index 00000000..4a132c5e --- /dev/null +++ b/2025-03/spring-05-springBoot/greeting-app/src/main/java/ru/otus/greetingapp/GreetingAppApplication.java @@ -0,0 +1,17 @@ +package ru.otus.greetingapp; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import ru.otus.greetingapp.config.OtusIOConfig; + + +//@EnableConfigurationProperties(OtusIOConfig.class) +@SpringBootApplication +public class GreetingAppApplication { + + public static void main(String[] args) { + SpringApplication.run(GreetingAppApplication.class, args); + } + +} diff --git a/2025-03/spring-05-springBoot/greeting-app/src/main/java/ru/otus/greetingapp/config/OtusIOConfig.java b/2025-03/spring-05-springBoot/greeting-app/src/main/java/ru/otus/greetingapp/config/OtusIOConfig.java new file mode 100644 index 00000000..ddb1b8c5 --- /dev/null +++ b/2025-03/spring-05-springBoot/greeting-app/src/main/java/ru/otus/greetingapp/config/OtusIOConfig.java @@ -0,0 +1,29 @@ +package ru.otus.greetingapp.config; + +import lombok.Getter; +import lombok.ToString; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.bind.ConstructorBinding; +import ru.otus.io.config.LocaleProvider; + +import java.util.Locale; + +@ToString +@ConfigurationProperties(prefix = "otus.custom") +public class OtusIOConfig implements LocaleProvider { + + @Getter + private final boolean ioEnabled; + private final Locale locale; + + @ConstructorBinding + public OtusIOConfig(boolean ioEnabled, String locale) { + this.ioEnabled = ioEnabled; + this.locale = Locale.forLanguageTag(locale); + } + + @Override + public Locale getCurrent() { + return locale; + } +} diff --git a/2025-03/spring-05-springBoot/greeting-app/src/main/java/ru/otus/greetingapp/runner/AppRunner.java b/2025-03/spring-05-springBoot/greeting-app/src/main/java/ru/otus/greetingapp/runner/AppRunner.java new file mode 100644 index 00000000..6547f1a8 --- /dev/null +++ b/2025-03/spring-05-springBoot/greeting-app/src/main/java/ru/otus/greetingapp/runner/AppRunner.java @@ -0,0 +1,47 @@ +package ru.otus.greetingapp.runner; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; +import ru.otus.greetingapp.config.OtusIOConfig; +import ru.otus.io.services.IOService; +import ru.otus.io.services.LocalizationService; + +import static java.util.Objects.isNull; + +@Component +public class AppRunner implements ApplicationRunner { + + private final OtusIOConfig ioConfig; + private final IOService ioService; + private final LocalizationService localizationService; + + public AppRunner(@Autowired(required = false) OtusIOConfig ioConfig, + @Autowired(required = false) IOService ioService, + @Autowired(required = false) LocalizationService localizationService) { + this.ioConfig = ioConfig; + this.ioService = ioService; + this.localizationService = localizationService; + } + + + @Override + public void run(ApplicationArguments args) { + if (isNull(ioService)) { + System.err.println("Отсутствует сервис ввода-вывода. Включите настройку \"otus.custom.io.enabled\""); + return; + } + ioService.outputString("---------------------------------------------"); + + ioService.outputAsString(ioConfig); + + ioService.outputString("---------------------------------------------"); + + var greetingTarget = localizationService.getMessage("greeting.target"); + var greeting = localizationService.getMessage("greeting", greetingTarget); + ioService.outputString(greeting); + + ioService.outputString("---------------------------------------------"); + } +} diff --git a/2025-03/spring-05-springBoot/greeting-app/src/main/resources/application.yml b/2025-03/spring-05-springBoot/greeting-app/src/main/resources/application.yml new file mode 100644 index 00000000..47bbd92b --- /dev/null +++ b/2025-03/spring-05-springBoot/greeting-app/src/main/resources/application.yml @@ -0,0 +1,9 @@ +#spring: + #messages: + #basename: messages + #fallback-to-system-locale: false + +#otus: + #custom: + #io-enabled: true + #locale: ru-RU \ No newline at end of file diff --git a/2025-03/spring-05-springBoot/greeting-app/src/main/resources/banner.txt b/2025-03/spring-05-springBoot/greeting-app/src/main/resources/banner.txt new file mode 100644 index 00000000..da1aa028 --- /dev/null +++ b/2025-03/spring-05-springBoot/greeting-app/src/main/resources/banner.txt @@ -0,0 +1,9 @@ + o o o o o + <|> <|> <|> <|> <|> + / > / \ / \ / \ < \ + \o__ __o o__ __o \o/ \o/ o__ __o o o o__ __o \o__ __o \o/ o__ __o/ + | v\ /v |> | | /v v\ <|> <|> /v v\ | |> | /v | + / \ <\ /> // / \ / \ /> <\ < > < > /> <\ / \ < > / \ /> / \ + \o/ o/ \o o/ \o/ \o/ \ / \o o/\o o/ \ / \o/ \o/ \ \o/ + | <| v\ /v __o | | o o v\ /v v\ /v o o | | o | + / \ / \ <\/> __/> / \ / \ <\__ __/> <\/> <\/> <\__ __/> / \ / \ <\__ / \ \ No newline at end of file diff --git a/2025-03/spring-05-springBoot/greeting-app/src/main/resources/messages.properties b/2025-03/spring-05-springBoot/greeting-app/src/main/resources/messages.properties new file mode 100644 index 00000000..2552c87d --- /dev/null +++ b/2025-03/spring-05-springBoot/greeting-app/src/main/resources/messages.properties @@ -0,0 +1,2 @@ +greeting=Hello {0}!!! +greeting.target=World \ No newline at end of file diff --git a/2025-03/spring-05-springBoot/greeting-app/src/main/resources/messages_en_US.properties b/2025-03/spring-05-springBoot/greeting-app/src/main/resources/messages_en_US.properties new file mode 100644 index 00000000..2552c87d --- /dev/null +++ b/2025-03/spring-05-springBoot/greeting-app/src/main/resources/messages_en_US.properties @@ -0,0 +1,2 @@ +greeting=Hello {0}!!! +greeting.target=World \ No newline at end of file diff --git a/2025-03/spring-05-springBoot/greeting-app/src/main/resources/messages_ru_RU.properties b/2025-03/spring-05-springBoot/greeting-app/src/main/resources/messages_ru_RU.properties new file mode 100644 index 00000000..b8cd2136 --- /dev/null +++ b/2025-03/spring-05-springBoot/greeting-app/src/main/resources/messages_ru_RU.properties @@ -0,0 +1,2 @@ +greeting=\u041F\u0440\u0438\u0432\u0435\u0442 {0}!!! +greeting.target=\u041C\u0438\u0440 \ No newline at end of file diff --git a/2025-03/spring-05-springBoot/io-starter/.gitignore b/2025-03/spring-05-springBoot/io-starter/.gitignore new file mode 100644 index 00000000..549e00a2 --- /dev/null +++ b/2025-03/spring-05-springBoot/io-starter/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.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/ diff --git a/2025-03/spring-05-springBoot/io-starter/pom.xml b/2025-03/spring-05-springBoot/io-starter/pom.xml new file mode 100644 index 00000000..77098d03 --- /dev/null +++ b/2025-03/spring-05-springBoot/io-starter/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + ru.otus + io-starter + 0.0.1-SNAPSHOT + io-starter + Spring Boot starter demo + + + 17 + 17 + 17 + UTF-8 + UTF-8 + 3.4.2 + 2.0 + 1.18.28 + + + + + org.springframework.boot + spring-boot-starter + ${spring.boot.version} + compile + + + + org.springframework.boot + spring-boot-configuration-processor + ${spring.boot.version} + + + + org.springframework.boot + spring-boot-autoconfigure + ${spring.boot.version} + compile + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.3.0 + + + false + + false + false + + + + + + + + + diff --git a/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/IOAutoconfiguration.java b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/IOAutoconfiguration.java new file mode 100644 index 00000000..aa31ac3e --- /dev/null +++ b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/IOAutoconfiguration.java @@ -0,0 +1,44 @@ +package ru.otus.io; + + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationContext; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.otus.io.config.DefaultLocaleProvider; +import ru.otus.io.config.LocaleProvider; +import ru.otus.io.services.IOService; +import ru.otus.io.services.LocalizationService; +import ru.otus.io.services.LocalizationServiceImpl; +import ru.otus.io.services.StreamsIOService; + +@ConditionalOnProperty(value = "otus.custom.io-enabled", havingValue = "true", matchIfMissing = true) +@Configuration +public class IOAutoconfiguration { + + @ConditionalOnMissingBean(IOService.class) + @Bean + public IOService ioService() { + return new StreamsIOService(System.out, System.in); + } + + @ConditionalOnMissingBean(LocaleProvider.class) + @Bean + public LocaleProvider localeProvider(@Value("${otus.custom.locale:en-US}") String localeTag) { + return new DefaultLocaleProvider(localeTag); + } + + @ConditionalOnMissingBean(LocalizationService.class) + @ConditionalOnBean(MessageSource.class) + @Bean + public LocalizationService localizationService(LocaleProvider localeProvider, + MessageSource messageSource) { + return new LocalizationServiceImpl(localeProvider, messageSource); + } + +} diff --git a/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/config/DefaultLocaleProvider.java b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/config/DefaultLocaleProvider.java new file mode 100644 index 00000000..f5a93df0 --- /dev/null +++ b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/config/DefaultLocaleProvider.java @@ -0,0 +1,17 @@ +package ru.otus.io.config; + +import java.util.Locale; + +public class DefaultLocaleProvider implements LocaleProvider { + + private final Locale locale; + + public DefaultLocaleProvider(String localeTag) { + this.locale = Locale.forLanguageTag(localeTag); + } + + @Override + public Locale getCurrent() { + return locale; + } +} diff --git a/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/config/LocaleProvider.java b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/config/LocaleProvider.java new file mode 100644 index 00000000..2ef1b06a --- /dev/null +++ b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/config/LocaleProvider.java @@ -0,0 +1,7 @@ +package ru.otus.io.config; + +import java.util.Locale; + +public interface LocaleProvider { + Locale getCurrent(); +} diff --git a/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/services/IOService.java b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/services/IOService.java new file mode 100644 index 00000000..5561be32 --- /dev/null +++ b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/services/IOService.java @@ -0,0 +1,8 @@ +package ru.otus.io.services; + +public interface IOService { + + void outputString(String s); + void outputAsString(Object o); + String readString(); +} diff --git a/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/services/LocalizationService.java b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/services/LocalizationService.java new file mode 100644 index 00000000..b912ea2d --- /dev/null +++ b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/services/LocalizationService.java @@ -0,0 +1,5 @@ +package ru.otus.io.services; + +public interface LocalizationService { + String getMessage(String key, Object ...args); +} diff --git a/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/services/LocalizationServiceImpl.java b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/services/LocalizationServiceImpl.java new file mode 100644 index 00000000..80a82751 --- /dev/null +++ b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/services/LocalizationServiceImpl.java @@ -0,0 +1,20 @@ +package ru.otus.io.services; + +import org.springframework.context.MessageSource; +import ru.otus.io.config.LocaleProvider; + +public class LocalizationServiceImpl implements LocalizationService { + + private final LocaleProvider localeProvider; + private final MessageSource messageSource; + + public LocalizationServiceImpl(LocaleProvider localeProvider, MessageSource messageSource) { + this.localeProvider = localeProvider; + this.messageSource = messageSource; + } + + @Override + public String getMessage(String key, Object... args) { + return messageSource.getMessage(key, args, localeProvider.getCurrent()); + } +} diff --git a/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/services/StreamsIOService.java b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/services/StreamsIOService.java new file mode 100644 index 00000000..3d22a649 --- /dev/null +++ b/2025-03/spring-05-springBoot/io-starter/src/main/java/ru/otus/io/services/StreamsIOService.java @@ -0,0 +1,31 @@ +package ru.otus.io.services; + +import java.io.InputStream; +import java.io.PrintStream; +import java.util.Scanner; + +public class StreamsIOService implements IOService { + + private final PrintStream ps; + private final Scanner sc; + + public StreamsIOService(PrintStream ps, InputStream is) { + this.ps = ps; + this.sc = new Scanner(is); + } + + @Override + public void outputString(String s) { + ps.println(s); + } + + @Override + public void outputAsString(Object o) { + ps.println(o); + } + + @Override + public String readString() { + return sc.nextLine(); + } +} diff --git a/2025-03/spring-05-springBoot/io-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/2025-03/spring-05-springBoot/io-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..f98b216a --- /dev/null +++ b/2025-03/spring-05-springBoot/io-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +ru.otus.io.IOAutoconfiguration \ No newline at end of file diff --git a/2025-03/spring-05-springBoot/pom.xml b/2025-03/spring-05-springBoot/pom.xml new file mode 100644 index 00000000..c7742646 --- /dev/null +++ b/2025-03/spring-05-springBoot/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + ru.otus + spring-boot-intro + 1.0 + + pom + + + greeting-app + io-starter + +