├── .gitignore ├── README.md ├── amber ├── .gitignore ├── README.md ├── img │ ├── java22-arrival.png │ └── project-amber-timeline.png ├── pom.xml ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ ├── Sandbox.java │ │ │ ├── collectionFactoryMethods │ │ │ └── ImageConverter.java │ │ │ ├── fileMismatch │ │ │ └── FileEqualsChecker.java │ │ │ ├── files │ │ │ └── FileService.java │ │ │ ├── httpClient │ │ │ └── TodoRepository.java │ │ │ ├── indent │ │ │ ├── NoIndentTextFormatter.java │ │ │ └── TextBlockFormatter.java │ │ │ ├── optionalOrElseThrow │ │ │ ├── DataProvider.java │ │ │ └── DataService.java │ │ │ ├── patternMatchingForInstanceof │ │ │ ├── Shape.java │ │ │ ├── ShapeDisplayNameResolver.java │ │ │ ├── withDisplayName │ │ │ │ ├── Circle.java │ │ │ │ ├── DisplayNamed.java │ │ │ │ └── Pentagon.java │ │ │ └── withNameShapes │ │ │ │ ├── Named.java │ │ │ │ ├── Square.java │ │ │ │ └── Triangle.java │ │ │ ├── record │ │ │ └── Car.java │ │ │ ├── sealed │ │ │ ├── Animal.java │ │ │ ├── Dog.java │ │ │ ├── Elephant.java │ │ │ ├── GermanShepherd.java │ │ │ ├── Human.java │ │ │ ├── Mammal.java │ │ │ └── Reptile.java │ │ │ ├── streamToList │ │ │ └── EvenNumberFilter.java │ │ │ ├── stringMethods │ │ │ └── StringService.java │ │ │ ├── switchExpressions │ │ │ ├── Day.java │ │ │ └── DayService.java │ │ │ ├── teeing │ │ │ ├── employee │ │ │ │ └── EmployeeService.java │ │ │ └── event │ │ │ │ └── ParticipationService.java │ │ │ ├── textBlock │ │ │ └── HtmlCode.java │ │ │ ├── transform │ │ │ ├── ImportedCSVTextProcessor.java │ │ │ └── PalindromeChecker.java │ │ │ ├── unmodifiableCollections │ │ │ ├── MyService.java │ │ │ └── Some3rdService.java │ │ │ └── var │ │ │ └── Student.java │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ ├── EnvironmentSetupTest.java │ │ ├── collectionFactoryMethods │ │ └── ImageConverterTest.java │ │ ├── fileMismatch │ │ └── FileEqualsCheckerTest.java │ │ ├── files │ │ └── FileServiceTest.java │ │ ├── httpClient │ │ └── TodoRepositoryTest.java │ │ ├── indent │ │ ├── NoIndentTextFormatterTest.java │ │ └── TextBlockFormatterTest.java │ │ ├── optionalOrElseThrow │ │ └── DataServiceTest.java │ │ ├── patternMatchingForInstanceof │ │ └── PatternMatchingForInstanceofTest.java │ │ ├── record │ │ └── CarTest.java │ │ ├── sealed │ │ └── AnimalTreeTest.java │ │ ├── streamToList │ │ └── EvenNumberFilterTest.java │ │ ├── stringMethods │ │ └── StringServiceTest.java │ │ ├── switchExpressions │ │ └── DayServiceTest.java │ │ ├── teeing │ │ ├── employee │ │ │ └── EmployeeServiceTest.java │ │ └── event │ │ │ └── ParticipationServiceTest.java │ │ ├── textBlock │ │ └── HtmlCodeTest.java │ │ ├── transform │ │ ├── ImportedCSVTextProcessorTest.java │ │ └── PalindromeCheckerTest.java │ │ ├── unmodifiableCollections │ │ └── MyServiceTest.java │ │ └── var │ │ └── StudentTest.java └── tmp │ └── java-versions-cheat-sheet-happycoders.eu-v22.0.3.pdf ├── bdd ├── .gitignore ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── docs │ ├── bdd-snippets.md │ ├── bdd-vs-tdd.png │ └── bdd.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── example │ │ ├── FizzBuzzProblem.java │ │ └── MyStack.java │ └── test │ ├── java │ └── com │ │ └── example │ │ └── bdd │ │ ├── DatatableExamplStepDefinitions.java │ │ ├── ExampleStepDefinitions.java │ │ ├── FizzBuzzProblemStepDefinitions.java │ │ ├── RunCucumberTest.java │ │ └── StackStepDefinition.java │ └── resources │ └── bdd │ ├── datatable.feature │ ├── example.feature │ ├── fizzbuzzproblem.feature │ └── stack.feature ├── clean-code ├── .gitignore ├── README.md ├── ZZPJ2024-clean_code_solid.pdf ├── pom.xml └── src │ ├── main │ └── java │ │ └── pl │ │ └── zzpj │ │ ├── cleancode │ │ └── doit.java │ │ └── solid │ │ ├── dip │ │ ├── driver │ │ │ ├── solution │ │ │ │ ├── Driver.java │ │ │ │ ├── RacingCar.java │ │ │ │ └── Vehicle.java │ │ │ └── violation │ │ │ │ ├── Driver.java │ │ │ │ ├── LimousineCar.java │ │ │ │ └── RacingCar.java │ │ └── weathertracker │ │ │ ├── solution │ │ │ └── TODO.txt │ │ │ └── violation │ │ │ ├── Emailer.java │ │ │ ├── Phone.java │ │ │ └── WeatherTracker.java │ │ ├── isp │ │ ├── contactbook │ │ │ ├── solution │ │ │ │ └── TODO.txt │ │ │ └── violation │ │ │ │ ├── Contact.java │ │ │ │ ├── Dialler.java │ │ │ │ ├── Emailer.java │ │ │ │ └── InterfaceSegregationPrincipleBAD.java │ │ └── switcher │ │ │ ├── solution │ │ │ ├── CameraSwitch.java │ │ │ ├── Car.java │ │ │ ├── Drone.java │ │ │ ├── EngineSwitch.java │ │ │ ├── RadioSwitch.java │ │ │ └── Vehicle.java │ │ │ └── violation │ │ │ ├── Car.java │ │ │ ├── Drone.java │ │ │ ├── Switches.java │ │ │ └── Vehicle.java │ │ ├── lsp │ │ ├── shape │ │ │ └── TODO.txt │ │ └── vehiclemovement │ │ │ ├── solution │ │ │ ├── Car.java │ │ │ ├── Gear.java │ │ │ ├── Plane.java │ │ │ └── Vehicle.java │ │ │ └── violation │ │ │ ├── Car.java │ │ │ ├── Gear.java │ │ │ ├── Plane.java │ │ │ └── Vehicle.java │ │ ├── ocp │ │ ├── greeter │ │ │ ├── solution │ │ │ │ ├── CasualPersonality.java │ │ │ │ ├── FormalPersonality.java │ │ │ │ ├── Greeter.java │ │ │ │ ├── IntimatePersonality.java │ │ │ │ └── Personality.java │ │ │ └── violation │ │ │ │ └── Greeter.java │ │ ├── usa │ │ │ ├── solution │ │ │ │ └── TODO.txt │ │ │ └── violation │ │ │ │ └── USASpeedLimitFines.java │ │ └── vehicle │ │ │ ├── solution │ │ │ ├── Comfort.java │ │ │ ├── DrivingMode.java │ │ │ ├── Economy.java │ │ │ ├── EventHandler.java │ │ │ ├── Sport.java │ │ │ └── Vehicle.java │ │ │ └── violation │ │ │ ├── DrivingMode.java │ │ │ ├── EventHandler.java │ │ │ └── Vehicle.java │ │ └── srp │ │ ├── book │ │ ├── solution │ │ │ └── TODO.txt │ │ └── violation │ │ │ └── BookAndPrinter.java │ │ └── vehicle │ │ ├── solution │ │ ├── FuelPump.java │ │ ├── Refualable.java │ │ └── Vehicle.java │ │ └── violation │ │ └── Vehicle.java │ └── test │ └── java │ └── .keep ├── intellij ├── README.md └── grupy │ └── README.md ├── intro ├── Git-Maven-GithubActions.md ├── ZZPJ2021-maven.pdf ├── jdk21-mint.png └── maven-helpful-snippets.md ├── microservices-world ├── README.md ├── TrainTripEcoSystem │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── zzpj │ │ │ │ └── TrainTripEcoSystem │ │ │ │ └── TrainTripEcoSystemApplication.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── zzpj │ │ └── TrainTripEcoSystem │ │ └── TrainTripEcoSystemApplicationTests.java ├── TrainTripManagerService │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── api │ │ └── train-api.yml │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── zzpj │ │ │ │ └── TrainTripManagerService │ │ │ │ └── TrainTripManagerServiceApplication.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── zzpj │ │ └── TrainTripManagerService │ │ └── TrainTripManagerServiceApplicationTests.java ├── TrainTripOrganizerService │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── api │ │ └── train-api.yml │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── zzpj │ │ │ │ └── TrainTripOrganizerService │ │ │ │ └── TrainTripOrganizerServiceApplication.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── zzpj │ │ └── TrainTripOrganizerService │ │ └── TrainTripOrganizerServiceApplicationTests.java ├── TrainTripUsersAdapter │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── zzpj │ │ │ │ └── TrainTripUsersAdapter │ │ │ │ └── TrainTripUsersAdapterApplication.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── zzpj │ │ └── TrainTripUsersAdapter │ │ └── TrainTripUsersAdapterApplicationTests.java ├── TrainTripsConfigServer │ ├── .gitignore │ ├── .mvn │ │ └── wrapper │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── zzpj │ │ │ │ └── TrainTripsConfigServer │ │ │ │ └── TrainTripsConfigServerApplication.java │ │ └── resources │ │ │ └── application.properties │ │ └── test │ │ └── java │ │ └── com │ │ └── zzpj │ │ └── TrainTripsConfigServer │ │ └── TrainTripsConfigServerApplicationTests.java └── train-api-example.yml ├── spring-security ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── SecurityDemoApplication.java │ │ │ ├── config │ │ │ └── SecurityConfig.java │ │ │ ├── controller │ │ │ ├── TokenProviderController.java │ │ │ └── UsersController.java │ │ │ ├── model │ │ │ ├── dao │ │ │ │ └── UserDao.java │ │ │ └── dto │ │ │ │ └── UserDto.java │ │ │ └── service │ │ │ └── UsersService.java │ └── resources │ │ ├── application.properties │ │ └── cert │ │ ├── cert.key │ │ └── cert.pub │ └── test │ └── java │ └── com │ └── example │ └── demo │ └── SecurityDemoApplicationTests.java └── spring ├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── ZZPJ2024-springboot.pdf ├── mvnw ├── mvnw.cmd ├── pom.xml ├── readme.md └── src ├── main ├── java │ └── com │ │ └── zzpj │ │ └── EventManager │ │ ├── EventConfig.java │ │ ├── EventExceptionHandler.java │ │ ├── EventManagerApplication.java │ │ ├── controller │ │ └── EventController.java │ │ ├── model │ │ ├── Event.java │ │ └── EventErrorResponse.java │ │ ├── repository │ │ └── EventRepository.java │ │ └── service │ │ └── EventService.java └── resources │ └── application.properties └── test └── java └── com └── zzpj └── EventManager └── EventManagerApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## PŁ: Zaawansowane Zagadnienia Programowania w Javie - Edycja 2024 2 | 3 | ### Prowadzący 4 | 5 | - dr inż. Łukasz Chomątek (lukasz.chomatek@p.lodz.pl) 6 | - mgr inż. Michal Dubel (michal.dubel.500@guest.p.lodz.pl priv: michal.dubel@ttpsc.pl) 7 | - mgr inż. Zbyszko Natkanski (zbyszko.natkanski.500@guest.p.lodz.pl priv: zbyszkonatkanski@gmail.com) 8 | 9 | ### Organizacja zajęć 10 | 11 | - Krótki wykład – przedstawienie problemu, rozwiązania lub technologii 12 | - Live coding 13 | - Ćwiczenia praktyczne 14 | 15 | ### Ramowy plan zajęć 16 | 17 | Lp | Temat | Data | Prowadzący | Uwagi 18 | ----|---------------------------------------------|------------|------------|-------------------------------------------------------------------------------------------------------- 19 | 1 | Wprowadzenie: Git/Maven/Github (Actions) | 28.02.2024 | ZN+MD | [Materiały na zajęcia](https://github.com/zzpj/pl-java2024/blob/main/intro/Git-Maven-GithubActions.md) 20 | 2 | IntelliJ Wizards | 6.03.2024 | MD | 21 | 3 | Unit Testing | 13.03.2024 | ZN+ŁCh | Testy parametryczne (Junit5) + Mocki (JMockito) + Cucumber-BDD 22 | 4 | Project concept | 20.03.2024 | ZN+MD+ŁCh | Zapisy na sloty czasowe są dostępne na platformie WIKAMP 23 | 5 | JDK Updates 8-21 | 27.03.2024 | ZN | 24 | 6 | LM Studio (AI w Javie) | 10.04.2024 | ŁCh | 25 | 7 | Spring 101 | 17.04.2024 | ZN | 26 | 8 | Spring 102 | 24.04.2024 | AK (MD) | 27 | 9 | Clean Code + SOLID + Statyczna analiza kodu | 8.05.2024 | ZN + ŁCh | 28 | 10 | Współbieżność | 15.05.2024 | ŁCh | 29 | 11 | Middle project check | 22.05.2024 | ZN+MD+ŁCh | Zapisy na sloty czasowe są dostępne na platformie WIKAMP 30 | 12 | Microservices Basis | 29.05.2024 | ZN | 31 | 13 | Microservices Advanced | 5.06.2024 | ZN | 32 | 14 | Testy mutacyjne | 12.06.2024 | MD | 33 | 15 | Final project check | 19.06.2024 | ZN+MD+ŁCh | Zapisy na sloty czasowe są dostępne na platformie WIKAMP 34 | 35 | 36 | ### Zaliczenie 37 | 38 | - Projekt grupowy (3-6 osób) 39 | - Elementy podlegające ocenie w projekcie grupowym: 40 | - Testy 41 | - Współpraca z Git/Github/CI(wedle uznania, proponowane: Github Actions)/IDE 42 | - Clean code 43 | - Programowanie funkcyjne 44 | - Wzorce projektowe 45 | - Użycie dodatkowych funkcjonalności spoza prezentowanych tematów (przykład: integracja z rozwiązaniem chmurowym np. 46 | deployment na publicznej chmurze) 47 | - Integracja z zewnętrznym zasobem po REST 48 | - Aktywność w realizacji projektu (PR, commity, githubowy pulse, board projektowy) 49 | - ... 50 | - *UI, UX nie mają znaczenia!* 51 | - *Unikać typowych aplikacji CRUD* 52 | - Aktywność i realizacja zadań z prezentowanego tematu (+0.5 do oceny końcowej) 53 | 54 | ### Linki 55 | 56 | https://p.lodz.pl/studenci/podzial-roku-akademickiego 57 | -------------------------------------------------------------------------------- /amber/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/**/target/ 4 | !**/src/test/**/target/ 5 | 6 | ### IntelliJ IDEA ### 7 | .idea/modules.xml 8 | .idea/jarRepositories.xml 9 | .idea/compiler.xml 10 | .idea/libraries/ 11 | *.iws 12 | *.iml 13 | *.ipr 14 | 15 | ### Eclipse ### 16 | .apt_generated 17 | .classpath 18 | .factorypath 19 | .project 20 | .settings 21 | .springBeans 22 | .sts4-cache 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | build/ 31 | !**/src/main/**/build/ 32 | !**/src/test/**/build/ 33 | 34 | ### VS Code ### 35 | .vscode/ 36 | 37 | ### Mac OS ### 38 | .DS_Store 39 | /.idea/ 40 | -------------------------------------------------------------------------------- /amber/img/java22-arrival.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzpj/pl-java2024/b3607327e97ffb15868a519cb595df959329c5f8/amber/img/java22-arrival.png -------------------------------------------------------------------------------- /amber/img/project-amber-timeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzpj/pl-java2024/b3607327e97ffb15868a519cb595df959329c5f8/amber/img/project-amber-timeline.png -------------------------------------------------------------------------------- /amber/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.example 8 | amber 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 21 13 | 21 14 | 15 | 16 | 17 | 18 | org.junit.jupiter 19 | junit-jupiter-engine 20 | 5.10.2 21 | test 22 | 23 | 24 | org.junit.jupiter 25 | junit-jupiter-params 26 | 5.10.2 27 | test 28 | 29 | 30 | org.projectlombok 31 | lombok 32 | 1.18.32 33 | provided 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/Sandbox.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | public class Sandbox { 4 | public static void main(String[] args) { 5 | } 6 | } -------------------------------------------------------------------------------- /amber/src/main/java/com/example/collectionFactoryMethods/ImageConverter.java: -------------------------------------------------------------------------------- 1 | package com.example.collectionFactoryMethods; 2 | 3 | import java.util.Set; 4 | import java.util.TreeSet; 5 | 6 | public class ImageConverter { 7 | private final String JPG_FILE_KEY = "jpg"; 8 | private final String PNG_FILE_KEY = "png"; 9 | private final String BMP_FILE_KEY = "bmp"; 10 | 11 | 12 | public Set getAvailableFileKeys() { 13 | // TODO: implement here 14 | // return immutable set of file keys 15 | 16 | return new TreeSet<>(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/fileMismatch/FileEqualsChecker.java: -------------------------------------------------------------------------------- 1 | package com.example.fileMismatch; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Path; 5 | 6 | public class FileEqualsChecker { 7 | 8 | boolean isFileEquals(Path path1, Path path2) throws IOException { 9 | // TODO: implement here 10 | return false; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/files/FileService.java: -------------------------------------------------------------------------------- 1 | package com.example.files; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Path; 5 | 6 | public class FileService { 7 | 8 | boolean isFileContainsText(Path path, String searchingText) throws IOException { 9 | // TODO: implement here 10 | // read file content and return true if searchingText found 11 | 12 | return false; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/httpClient/TodoRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.httpClient; 2 | 3 | import java.io.IOException; 4 | import java.net.URI; 5 | import java.net.URISyntaxException; 6 | import java.net.http.HttpClient; 7 | import java.net.http.HttpRequest; 8 | import java.net.http.HttpResponse; 9 | 10 | public class TodoRepository { 11 | 12 | String getTodo() throws URISyntaxException, IOException, InterruptedException { 13 | // TODO: implement here 14 | // use HttpResponse.BodyHandlers.ofString() handler 15 | // return response body 16 | 17 | return ""; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/indent/NoIndentTextFormatter.java: -------------------------------------------------------------------------------- 1 | package com.example.indent; 2 | 3 | public class NoIndentTextFormatter { 4 | 5 | String noIndentText(String text) { 6 | // TODO: implement here 7 | // remove indent 8 | 9 | return ""; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/indent/TextBlockFormatter.java: -------------------------------------------------------------------------------- 1 | package com.example.indent; 2 | 3 | public class TextBlockFormatter { 4 | private final int CODE_TEXT_BLOCK_INDENT = 4; 5 | 6 | String formatLinesToCodeBlockIndent(String code) { 7 | // TODO: implement here 8 | // use CODE_TEXT_BLOCK_INDENT as padding value 9 | 10 | return ""; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/optionalOrElseThrow/DataProvider.java: -------------------------------------------------------------------------------- 1 | package com.example.optionalOrElseThrow; 2 | 3 | import java.util.Optional; 4 | 5 | public class DataProvider { 6 | 7 | // do not change 8 | Optional getUsername(int id) { 9 | return id < 3 10 | ? Optional.empty() 11 | : Optional.of("user-" + id); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/optionalOrElseThrow/DataService.java: -------------------------------------------------------------------------------- 1 | package com.example.optionalOrElseThrow; 2 | 3 | public class DataService { 4 | DataProvider dataProvider = new DataProvider(); 5 | 6 | String getUsername(int id) { 7 | // TODO: implement here 8 | // get username from DataProvider. 9 | // Return value or throw exception if there is no value 10 | 11 | return ""; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/patternMatchingForInstanceof/Shape.java: -------------------------------------------------------------------------------- 1 | package com.example.patternMatchingForInstanceof; 2 | 3 | public class Shape { 4 | } 5 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/patternMatchingForInstanceof/ShapeDisplayNameResolver.java: -------------------------------------------------------------------------------- 1 | package com.example.patternMatchingForInstanceof; 2 | 3 | public class ShapeDisplayNameResolver { 4 | 5 | public String resolveShape(Shape shape) { 6 | // TODO: implement here with pattern matching for instanceof usage 7 | 8 | 9 | return ""; 10 | } 11 | } 12 | 13 | // TIP: shape can be DisplayNamed or Named 14 | // if shape is DisplayNamed use getDisplayName method 15 | // if shape is Named use getName method and format it to expected display string 16 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/patternMatchingForInstanceof/withDisplayName/Circle.java: -------------------------------------------------------------------------------- 1 | package com.example.patternMatchingForInstanceof.withDisplayName; 2 | 3 | import com.example.patternMatchingForInstanceof.Shape; 4 | 5 | public class Circle extends Shape implements DisplayNamed { 6 | @Override 7 | public String getDisplayName() { 8 | return "This is circle name!"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/patternMatchingForInstanceof/withDisplayName/DisplayNamed.java: -------------------------------------------------------------------------------- 1 | package com.example.patternMatchingForInstanceof.withDisplayName; 2 | 3 | public interface DisplayNamed { 4 | 5 | String getDisplayName(); 6 | } 7 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/patternMatchingForInstanceof/withDisplayName/Pentagon.java: -------------------------------------------------------------------------------- 1 | package com.example.patternMatchingForInstanceof.withDisplayName; 2 | 3 | import com.example.patternMatchingForInstanceof.Shape; 4 | 5 | public class Pentagon extends Shape implements DisplayNamed { 6 | @Override 7 | public String getDisplayName() { 8 | return "This is pentagon name!"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/patternMatchingForInstanceof/withNameShapes/Named.java: -------------------------------------------------------------------------------- 1 | package com.example.patternMatchingForInstanceof.withNameShapes; 2 | 3 | public interface Named { 4 | String getName(); 5 | } 6 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/patternMatchingForInstanceof/withNameShapes/Square.java: -------------------------------------------------------------------------------- 1 | package com.example.patternMatchingForInstanceof.withNameShapes; 2 | 3 | import com.example.patternMatchingForInstanceof.Shape; 4 | 5 | public class Square extends Shape implements Named { 6 | @Override 7 | public String getName() { 8 | return "square"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/patternMatchingForInstanceof/withNameShapes/Triangle.java: -------------------------------------------------------------------------------- 1 | package com.example.patternMatchingForInstanceof.withNameShapes; 2 | 3 | import com.example.patternMatchingForInstanceof.Shape; 4 | 5 | public class Triangle extends Shape implements Named{ 6 | @Override 7 | public String getName() { 8 | return "triangle"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/record/Car.java: -------------------------------------------------------------------------------- 1 | package com.example.record; 2 | 3 | // TODO: implement here 4 | // change this class to record 5 | // throw IllegalArgumentException when capacity in negative while creating 6 | public class Car { 7 | 8 | 9 | public Car(String make, int capacity) { 10 | 11 | } 12 | 13 | public String make() { 14 | return ""; 15 | } 16 | 17 | public int capacity() { 18 | return 0; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/sealed/Animal.java: -------------------------------------------------------------------------------- 1 | package com.example.sealed; 2 | 3 | public class Animal { 4 | } 5 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/sealed/Dog.java: -------------------------------------------------------------------------------- 1 | package com.example.sealed; 2 | 3 | public class Dog { 4 | } 5 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/sealed/Elephant.java: -------------------------------------------------------------------------------- 1 | package com.example.sealed; 2 | 3 | public class Elephant { 4 | } 5 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/sealed/GermanShepherd.java: -------------------------------------------------------------------------------- 1 | package com.example.sealed; 2 | 3 | public class GermanShepherd { 4 | } 5 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/sealed/Human.java: -------------------------------------------------------------------------------- 1 | package com.example.sealed; 2 | 3 | public class Human { 4 | } 5 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/sealed/Mammal.java: -------------------------------------------------------------------------------- 1 | package com.example.sealed; 2 | 3 | public class Mammal { 4 | } 5 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/sealed/Reptile.java: -------------------------------------------------------------------------------- 1 | package com.example.sealed; 2 | 3 | public class Reptile { 4 | } 5 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/streamToList/EvenNumberFilter.java: -------------------------------------------------------------------------------- 1 | package com.example.streamToList; 2 | 3 | import java.util.List; 4 | 5 | public class EvenNumberFilter { 6 | 7 | List getEvenNumbers(List allNumbers) { 8 | // TODO: implement here 9 | // return only even numbers from input list 10 | // 1. transform list to Stream 11 | // 2. filter by Stream::filter method 12 | // 3. collect to list 13 | 14 | 15 | return allNumbers; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/stringMethods/StringService.java: -------------------------------------------------------------------------------- 1 | package com.example.stringMethods; 2 | 3 | import java.util.List; 4 | 5 | public class StringService { 6 | 7 | List getOnlyNotBlankStrings(List input) { 8 | // TODO: implement here 9 | 10 | return input; 11 | } 12 | 13 | List getStrippedTextLines(String text) { 14 | // TODO: implement here 15 | // split text to lines and strip 16 | return null; 17 | } 18 | 19 | List extendFoundStringByRepeatSomeTimes(List list, String searchedText, int nTimesRepeat) { 20 | // TODO: implement here 21 | // search for searchedText in a list. Change this string by repeat n times if found 22 | return list; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/switchExpressions/Day.java: -------------------------------------------------------------------------------- 1 | package com.example.switchExpressions; 2 | 3 | public enum Day { 4 | 5 | SUNDAY, MONDAY, TUESDAY, 6 | WEDNESDAY, THURSDAY, FRIDAY, SATURDAY; 7 | } 8 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/switchExpressions/DayService.java: -------------------------------------------------------------------------------- 1 | package com.example.switchExpressions; 2 | 3 | public class DayService { 4 | 5 | int getDayNumberOfLettersForWorkday(Day day) { 6 | // TODO: implement here 7 | // return number of letters for working days or throw exception for the other 8 | 9 | return 0; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/teeing/employee/EmployeeService.java: -------------------------------------------------------------------------------- 1 | package com.example.teeing.employee; 2 | 3 | import java.util.List; 4 | 5 | 6 | class Employee { 7 | private double salary; 8 | 9 | public Employee(double salary) { 10 | this.salary = salary; 11 | } 12 | 13 | public double getSalary() { 14 | return salary; 15 | } 16 | } 17 | 18 | public class EmployeeService { 19 | 20 | double getAvgEmployeeSalary(List employees) { 21 | // TODO: implement here 22 | // use List::stream method 23 | 24 | return 0.0; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/teeing/event/ParticipationService.java: -------------------------------------------------------------------------------- 1 | package com.example.teeing.event; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | class Guest { 7 | private final String name; 8 | private boolean participating; 9 | private Integer participantsNumber; 10 | 11 | public Guest(String name, boolean participating, 12 | Integer participantsNumber) { 13 | this.name = name; 14 | this.participating = participating; 15 | this.participantsNumber = participantsNumber; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public boolean isParticipating() { 23 | return participating; 24 | } 25 | 26 | public Integer getParticipantsNumber() { 27 | return participantsNumber; 28 | } 29 | } 30 | 31 | class EventParticipation { 32 | private final List guestNameList; 33 | private final Integer totalNumberOfParticipants; 34 | 35 | public EventParticipation(List guestNameList, 36 | Integer totalNumberOfParticipants) { 37 | this.guestNameList = guestNameList; 38 | this.totalNumberOfParticipants = totalNumberOfParticipants; 39 | } 40 | 41 | public List getGuestNameList() { 42 | return guestNameList; 43 | } 44 | 45 | public Integer getTotalNumberOfParticipants() { 46 | return totalNumberOfParticipants; 47 | } 48 | 49 | } 50 | 51 | public class ParticipationService { 52 | 53 | EventParticipation processEventGuests(List guests) { 54 | // TODO: implement here 55 | // return EventParticipation with sum of all participants and names of participants, who will attend 56 | 57 | // TIP 58 | // collector1: use Collectors.filtering for filtering ony attend guests, 59 | // then collect theirs names to list (use Collectors.mapping) 60 | // collector2: return sum of all participants 61 | 62 | 63 | return new EventParticipation(Collections.emptyList(), 0); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/textBlock/HtmlCode.java: -------------------------------------------------------------------------------- 1 | package com.example.textBlock; 2 | 3 | public class HtmlCode { 4 | String getHtml() { 5 | // TODO: implement here 6 | // rewrite using text block 7 | 8 | return "\n" + 9 | "\n" + 10 | " \n" + 11 | " \n" + 12 | " My test page\n" + 13 | " \n" + 14 | " \n" + 15 | " \"My\n" + 16 | " \n" + 17 | "\n"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/transform/ImportedCSVTextProcessor.java: -------------------------------------------------------------------------------- 1 | package com.example.transform; 2 | 3 | public class ImportedCSVTextProcessor { 4 | 5 | String process(String line) { 6 | // TODO: implement here 7 | // 1. replace "," with space 8 | // 2. remove "none" 9 | // 3. remove white spaces from start and end 10 | // 4. add "-done" at the end 11 | // 5. to uppercase 12 | 13 | return ""; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/transform/PalindromeChecker.java: -------------------------------------------------------------------------------- 1 | package com.example.transform; 2 | 3 | public class PalindromeChecker { 4 | 5 | boolean isPalindrome(String text) { 6 | // TODO: implement here 7 | // TIP: you can use StringBuilder.reverse method 8 | 9 | 10 | return false; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/unmodifiableCollections/MyService.java: -------------------------------------------------------------------------------- 1 | package com.example.unmodifiableCollections; 2 | 3 | import java.util.List; 4 | 5 | public class MyService { 6 | Some3rdService some3rdService = new Some3rdService(); 7 | 8 | public List getUnmodifiableListByCollector() { 9 | // TODO: implement here 10 | // copy list by stream and Collectors.toUnmodifiableList 11 | 12 | return some3rdService.getList(); 13 | } 14 | 15 | public List getUnmodifiableListByCopy() { 16 | // TODO: implement here 17 | // copy list by static copyOf method 18 | 19 | return some3rdService.getList(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/unmodifiableCollections/Some3rdService.java: -------------------------------------------------------------------------------- 1 | package com.example.unmodifiableCollections; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Some3rdService { 7 | 8 | // return modifiable list by default. Do not change. 9 | public List getList() { 10 | List list = new ArrayList<>(); 11 | list.add(1); 12 | list.add(2); 13 | list.add(3); 14 | list.add(4); 15 | return list; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /amber/src/main/java/com/example/var/Student.java: -------------------------------------------------------------------------------- 1 | package com.example.var; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.RoundingMode; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class Student { 9 | private final Integer[] marks; 10 | 11 | public Student(Integer[] marks) { 12 | this.marks = marks; 13 | } 14 | 15 | public Integer getNumberOfMarks() { 16 | return marks.length; 17 | } 18 | 19 | // TODO: implement here 20 | // rewrite code using var from JDK 10 21 | 22 | public Integer getTotalSumOfMarks() { 23 | Integer sum = 0; 24 | for (Integer mark : marks) { 25 | sum += mark; 26 | } 27 | return sum; 28 | } 29 | 30 | public BigDecimal getAverageOfMarks() { 31 | Integer sum = getTotalSumOfMarks(); 32 | return new BigDecimal(sum) 33 | .divide(new BigDecimal(marks.length), 3, RoundingMode.UP); 34 | } 35 | 36 | public Integer getMaximumMark() { 37 | Integer max = Integer.MIN_VALUE; 38 | for (Integer mark : marks) { 39 | if (mark > max) { 40 | max = mark; 41 | } 42 | } 43 | return max; 44 | } 45 | 46 | public Integer getMinimumMark() { 47 | Integer min = Integer.MAX_VALUE; 48 | for (Integer mark : marks) { 49 | if (mark < min) { 50 | min = mark; 51 | } 52 | } 53 | return min; 54 | } 55 | 56 | public List getDistinctMarks() { 57 | List distinctMarks = new ArrayList<>(); 58 | 59 | for (Integer mark : marks) { 60 | if (!distinctMarks.contains(mark)) { 61 | distinctMarks.add(mark); 62 | } 63 | } 64 | return distinctMarks; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/EnvironmentSetupTest.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | 7 | public class EnvironmentSetupTest { 8 | 9 | @Test 10 | void shouldRunOnJava22() { 11 | int feature = Runtime.version().feature(); 12 | assertEquals(22, feature); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/collectionFactoryMethods/ImageConverterTest.java: -------------------------------------------------------------------------------- 1 | package com.example.collectionFactoryMethods; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.Set; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | import static org.junit.jupiter.api.Assertions.assertThrows; 9 | 10 | class ImageConverterTest { 11 | 12 | @Test 13 | void shouldReturnImmutableFileKeysList() { 14 | ImageConverter sut = new ImageConverter(); 15 | 16 | Set result = sut.getAvailableFileKeys(); 17 | 18 | assertEquals(3, result.size()); 19 | assertThrows(UnsupportedOperationException.class, () -> { 20 | result.add("gif"); 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/fileMismatch/FileEqualsCheckerTest.java: -------------------------------------------------------------------------------- 1 | package com.example.fileMismatch; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.io.IOException; 6 | import java.nio.file.Files; 7 | import java.nio.file.Path; 8 | 9 | import static org.junit.jupiter.api.Assertions.*; 10 | 11 | class FileEqualsCheckerTest { 12 | FileEqualsChecker checker = new FileEqualsChecker(); 13 | 14 | @Test 15 | void shouldReturnTrueIfFilesAreEquals() throws IOException { 16 | Path path1 = Files.createTempFile("text1", ".txt"); 17 | Files.writeString(path1,"value1"); 18 | 19 | Path path2 = Files.createTempFile("text2", ".txt"); 20 | Files.writeString(path2,"value1"); 21 | 22 | 23 | boolean result = checker.isFileEquals(path1, path2); 24 | 25 | assertTrue(result); 26 | } 27 | @Test 28 | void shouldReturnFalseIfFilesAreNotEquals() throws IOException { 29 | Path path1 = Files.createTempFile("text1", ".txt"); 30 | Files.writeString(path1,"value1"); 31 | 32 | Path path2 = Files.createTempFile("text2", ".txt"); 33 | Files.writeString(path2,"value2"); 34 | 35 | 36 | boolean result = checker.isFileEquals(path1, path2); 37 | 38 | assertFalse(result); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/files/FileServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.example.files; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.io.IOException; 6 | import java.nio.file.Files; 7 | import java.nio.file.Path; 8 | 9 | import static org.junit.jupiter.api.Assertions.*; 10 | 11 | class FileServiceTest { 12 | 13 | @Test 14 | void shouldReturnFalseIfNotFound() throws IOException { 15 | FileService service = new FileService(); 16 | Path filePath = Files.writeString(Files.createTempFile("file", ".txt"), "Sample text"); 17 | 18 | boolean result = service.isFileContainsText(filePath, "not found"); 19 | 20 | assertFalse(result); 21 | } 22 | 23 | @Test 24 | void shouldReturnTrueIfFound() throws IOException { 25 | FileService service = new FileService(); 26 | Path filePath = Files.writeString(Files.createTempFile("file", ".txt"), "Sample text "); 27 | 28 | boolean result = service.isFileContainsText(filePath, "Sample text"); 29 | 30 | assertTrue(result); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/httpClient/TodoRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.example.httpClient; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.io.IOException; 6 | import java.net.URISyntaxException; 7 | 8 | import static org.junit.jupiter.api.Assertions.*; 9 | 10 | class TodoRepositoryTest { 11 | 12 | @Test 13 | void getTodo() throws URISyntaxException, IOException, InterruptedException { 14 | TodoRepository repository = new TodoRepository(); 15 | 16 | String result = repository.getTodo(); 17 | assertEquals("{\n" + 18 | " \"userId\": 1,\n" + 19 | " \"id\": 1,\n" + 20 | " \"title\": \"delectus aut autem\",\n" + 21 | " \"completed\": false\n" + 22 | "}", result); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/indent/NoIndentTextFormatterTest.java: -------------------------------------------------------------------------------- 1 | package com.example.indent; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | class NoIndentTextFormatterTest { 8 | 9 | NoIndentTextFormatter noIndentTextFormatter = new NoIndentTextFormatter(); 10 | 11 | @Test 12 | void noIndentText() { 13 | String text = " some code with big\n indent\n"; 14 | 15 | String result = noIndentTextFormatter.noIndentText(text); 16 | 17 | assertEquals("some code with big\nindent\n", result); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/indent/TextBlockFormatterTest.java: -------------------------------------------------------------------------------- 1 | package com.example.indent; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | class TextBlockFormatterTest { 8 | TextBlockFormatter textBlockFormatter = new TextBlockFormatter(); 9 | 10 | @Test 11 | void formatLinesToCodeBlockIndent() { 12 | String text = "Code line 1\nCode line 2\nCode line 3\n"; 13 | 14 | 15 | String result = textBlockFormatter.formatLinesToCodeBlockIndent(text); 16 | 17 | assertEquals( 18 | " Code line 1\n" + 19 | " Code line 2\n" + 20 | " Code line 3\n", 21 | result); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/optionalOrElseThrow/DataServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.example.optionalOrElseThrow; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.NoSuchElementException; 6 | 7 | import static org.junit.jupiter.api.Assertions.*; 8 | 9 | class DataServiceTest { 10 | DataService dataService = new DataService(); 11 | 12 | 13 | @Test 14 | void shouldReturnUsernameForIdGreaterThan3() { 15 | String username = dataService.getUsername(4); 16 | 17 | assertEquals("user-4", username); 18 | } 19 | 20 | @Test 21 | void shouldThrowExceptionForIdLessThan3() { 22 | 23 | assertThrows(NoSuchElementException.class, () -> { 24 | dataService.getUsername(1); 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/patternMatchingForInstanceof/PatternMatchingForInstanceofTest.java: -------------------------------------------------------------------------------- 1 | package com.example.patternMatchingForInstanceof; 2 | 3 | import com.example.patternMatchingForInstanceof.withDisplayName.Circle; 4 | import com.example.patternMatchingForInstanceof.withDisplayName.Pentagon; 5 | import com.example.patternMatchingForInstanceof.withNameShapes.Square; 6 | import com.example.patternMatchingForInstanceof.withNameShapes.Triangle; 7 | import org.junit.jupiter.api.Test; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | 11 | public class PatternMatchingForInstanceofTest { 12 | private ShapeDisplayNameResolver sut = new ShapeDisplayNameResolver(); 13 | 14 | @Test 15 | void shouldProvideCircleShapeDisplayName() { 16 | ShapeDisplayNameResolver sut = new ShapeDisplayNameResolver(); 17 | Circle circle = new Circle(); 18 | 19 | String result = sut.resolveShape(circle); 20 | 21 | assertEquals("This is circle name!", result); 22 | } 23 | 24 | @Test 25 | void shouldProvideSquareShapeDisplayName() { 26 | ShapeDisplayNameResolver sut = new ShapeDisplayNameResolver(); 27 | Square square = new Square(); 28 | 29 | String result = sut.resolveShape(square); 30 | 31 | assertEquals("This is square name!", result); 32 | } 33 | 34 | @Test 35 | void shouldProvideTriangleShapeDisplayName() { 36 | ShapeDisplayNameResolver sut = new ShapeDisplayNameResolver(); 37 | Triangle triangle = new Triangle(); 38 | 39 | String result = sut.resolveShape(triangle); 40 | 41 | assertEquals("This is triangle name!", result); 42 | } 43 | @Test 44 | void shouldProvidePentagonShapeDisplayName() { 45 | ShapeDisplayNameResolver sut = new ShapeDisplayNameResolver(); 46 | Pentagon pentagon = new Pentagon(); 47 | 48 | String result = sut.resolveShape(pentagon); 49 | 50 | assertEquals("This is pentagon name!", result); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/record/CarTest.java: -------------------------------------------------------------------------------- 1 | package com.example.record; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | class CarTest { 8 | 9 | @Test 10 | void shouldSaveMarkAndCapacity() { 11 | Car car = new Car("Fiat", 1400); 12 | 13 | assertEquals("Fiat", car.make()); 14 | assertEquals(1400, car.capacity()); 15 | } 16 | 17 | @Test 18 | void shouldThrowExceptionForNegativeCapacityValue() { 19 | 20 | assertThrows(IllegalArgumentException.class, () -> { 21 | new Car("Fiat", -2); 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/sealed/AnimalTreeTest.java: -------------------------------------------------------------------------------- 1 | package com.example.sealed; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.lang.reflect.Modifier; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertTrue; 8 | 9 | 10 | public class AnimalTreeTest { 11 | 12 | /* 13 | How Animal tree inheritance should look: 14 | Animal --- 15 | | 16 | |--- Reptile 17 | |--- Mammal --- 18 | | 19 | |--- Elephant 20 | |--- Human 21 | |--- Dog --- 22 | | 23 | |--- GermanShepherd 24 | 25 | Requirements: 26 | * Only Reptile and Mammal can extend Animal 27 | * Any class can extend Mammal. 28 | * There is no way to extend GermanShepherd 29 | */ 30 | 31 | @Test 32 | void shouldReptileIsChildOfAnimal() { 33 | Object reptile = new Reptile(); 34 | 35 | assertTrue(reptile instanceof Animal); 36 | } 37 | 38 | @Test 39 | void shouldMammalIsChildOfAnimal() { 40 | Object object = new Mammal(); 41 | assertTrue(object instanceof Animal); 42 | } 43 | 44 | @Test 45 | void shouldElephantIsChildOfMammal() { 46 | Object object = new Elephant(); 47 | assertTrue(object instanceof Mammal); 48 | } 49 | 50 | @Test 51 | void shouldHumanIsChildOfMammal() { 52 | Object object = new Human(); 53 | assertTrue(object instanceof Mammal); 54 | } 55 | 56 | @Test 57 | void shouldDogIsChildOfMammal() { 58 | Object object = new Dog(); 59 | assertTrue(object instanceof Mammal); 60 | } 61 | 62 | @Test 63 | void shouldGermanShepherdIsChildOfDog() { 64 | Object object = new GermanShepherd(); 65 | assertTrue(object instanceof Dog); 66 | } 67 | 68 | @Test 69 | void shouldGermanShepherdIsFinal() { 70 | Object object = new GermanShepherd(); 71 | assertTrue(Modifier.isFinal(GermanShepherd.class.getModifiers())); 72 | } 73 | } 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | /* 129 | SOLUTION: 130 | public sealed class Animal permits Mammal, Reptile 131 | public class Dog extends Mammal 132 | public class Elephant extends Mammal 133 | public final class GermanShepherd extends Dog 134 | public class Human extends Mammal 135 | public non-sealed class Mammal extends Animal 136 | public non-sealed class Reptile extends Animal 137 | */ 138 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/streamToList/EvenNumberFilterTest.java: -------------------------------------------------------------------------------- 1 | package com.example.streamToList; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.List; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | public class EvenNumberFilterTest { 10 | @Test 11 | void shouldReturnOnlyEvenNumbers() { 12 | 13 | EvenNumberFilter sut = new EvenNumberFilter(); 14 | 15 | List result = sut.getEvenNumbers(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9)); 16 | 17 | assertEquals(List.of(2, 4, 6, 8), result); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/stringMethods/StringServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.example.stringMethods; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertEquals; 9 | 10 | class StringServiceTest { 11 | StringService sut = new StringService(); 12 | 13 | @Test 14 | void shouldGetOnlyNotBlankStrings() { 15 | List input = Arrays. 16 | asList( 17 | "text1", 18 | "----", 19 | "", 20 | " ", 21 | " A ", 22 | "\n ", 23 | " \r" 24 | ); 25 | List result = sut.getOnlyNotBlankStrings(input); 26 | 27 | assertEquals(Arrays.asList("text1", "----", " A "), result); 28 | } 29 | 30 | @Test 31 | void shouldGetStrippedTextLines() { 32 | String lorem = " Lorem ipsum dolor sit amet \n" + 33 | " consectetur \n a\ndipiscing elit.\r" + 34 | "Mauris sed diam eleifend rhoncus sem non rhoncus velit.\n"; 35 | List result = sut.getStrippedTextLines(lorem); 36 | 37 | assertEquals(Arrays.asList("Lorem ipsum dolor sit amet","consectetur","a", "dipiscing elit.", "Mauris sed diam eleifend rhoncus sem non rhoncus velit."), result); 38 | } 39 | 40 | @Test 41 | void shouldExtendByRepeatFoundStringSomeTimes() { 42 | 43 | List input = Arrays.asList("some", "example", "string", "list"); 44 | 45 | List result = sut.extendFoundStringByRepeatSomeTimes(input,"list", 3); 46 | 47 | assertEquals(Arrays.asList("some", "example", "string", "listlistlist"), result); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/switchExpressions/DayServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.example.switchExpressions; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | import static org.junit.jupiter.api.Assertions.assertThrows; 7 | 8 | class DayServiceTest { 9 | DayService dayService = new DayService(); 10 | 11 | @Test 12 | void shouldReturnProperValueForMonday() { 13 | int result = dayService.getDayNumberOfLettersForWorkday(Day.MONDAY); 14 | 15 | assertEquals(6, result); 16 | } 17 | 18 | @Test 19 | void shouldReturnProperValueForTuesday() { 20 | int result = dayService.getDayNumberOfLettersForWorkday(Day.TUESDAY); 21 | 22 | assertEquals(7, result); 23 | } 24 | 25 | @Test 26 | void shouldReturnProperValueForThursday() { 27 | int result = dayService.getDayNumberOfLettersForWorkday(Day.THURSDAY); 28 | 29 | assertEquals(8, result); 30 | } 31 | 32 | @Test 33 | void shouldReturnProperValueForWednesday() { 34 | int result = dayService.getDayNumberOfLettersForWorkday(Day.WEDNESDAY); 35 | 36 | assertEquals(9, result); 37 | } 38 | 39 | @Test 40 | void shouldThrowExceptionForNonWorkingDay() { 41 | 42 | assertThrows(IllegalStateException.class, () -> { 43 | dayService.getDayNumberOfLettersForWorkday(Day.SUNDAY); 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/teeing/employee/EmployeeServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.example.teeing.employee; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.List; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | class EmployeeServiceTest { 10 | EmployeeService employeeService = new EmployeeService(); 11 | 12 | @Test 13 | void getAvgEmployeeSalary() { 14 | 15 | List employees = List.of( 16 | new Employee(10), 17 | new Employee(20), 18 | new Employee(30), 19 | new Employee(40), 20 | new Employee(50) 21 | ); 22 | 23 | double result = employeeService.getAvgEmployeeSalary(employees); 24 | 25 | assertEquals(30.0, result); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/teeing/event/ParticipationServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.example.teeing.event; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | 8 | import static org.junit.jupiter.api.Assertions.*; 9 | 10 | class ParticipationServiceTest { 11 | 12 | @Test 13 | void processEventGuests() { 14 | List guests = List.of( 15 | new Guest("name1", true, 10), 16 | new Guest("name2", false, 2), 17 | new Guest("name3", true, 5) 18 | ); 19 | ParticipationService participationService = new ParticipationService(); 20 | EventParticipation eventParticipation = participationService.processEventGuests(guests); 21 | 22 | assertEquals(eventParticipation.getGuestNameList(), Arrays.asList("name1", "name3")); 23 | assertEquals(17, eventParticipation.getTotalNumberOfParticipants()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/textBlock/HtmlCodeTest.java: -------------------------------------------------------------------------------- 1 | package com.example.textBlock; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | class HtmlCodeTest { 8 | 9 | @Test 10 | void getHtml() { 11 | HtmlCode htmlCode = new HtmlCode(); 12 | 13 | String result = htmlCode.getHtml(); 14 | 15 | assertEquals("\n" + 16 | "\n" + 17 | " \n" + 18 | " \n" + 19 | " My test page\n" + 20 | " \n" + 21 | " \n" + 22 | " \"My\n" + 23 | " \n" + 24 | "\n", result); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/transform/ImportedCSVTextProcessorTest.java: -------------------------------------------------------------------------------- 1 | package com.example.transform; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | 7 | class ImportedCSVTextProcessorTest { 8 | 9 | @Test 10 | void process() { 11 | ImportedCSVTextProcessor sut = new ImportedCSVTextProcessor(); 12 | 13 | String result = sut.process("\n \nLorem,Ipsum,is, simply,dummy,text none,of, the ,printing,and,typesetting,industry., Lorem,Ipsum,has,"); 14 | 15 | assertEquals("LOREM IPSUM IS SIMPLY DUMMY TEXT OF THE PRINTING AND TYPESETTING INDUSTRY. LOREM IPSUM HAS-DONE", result 16 | ); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/transform/PalindromeCheckerTest.java: -------------------------------------------------------------------------------- 1 | package com.example.transform; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.params.ParameterizedTest; 5 | import org.junit.jupiter.params.provider.ValueSource; 6 | 7 | import static org.junit.jupiter.api.Assertions.*; 8 | 9 | class PalindromeCheckerTest { 10 | 11 | PalindromeChecker checker = new PalindromeChecker(); 12 | 13 | @ParameterizedTest 14 | @ValueSource(strings = {"zaraz","kajak","anna","sedes","mam", "ala","radar"}) 15 | void shouldReturnTrueForPalindrome(String text) { 16 | boolean result = checker.isPalindrome(text); 17 | 18 | assertTrue(result); 19 | } 20 | 21 | @Test 22 | void shouldReturnFalseForNonPalindrome() { 23 | boolean result = checker.isPalindrome("Programowanie"); 24 | 25 | assertFalse(result); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/unmodifiableCollections/MyServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.example.unmodifiableCollections; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.List; 6 | 7 | import static org.junit.jupiter.api.Assertions.*; 8 | 9 | class MyServiceTest { 10 | MyService myService = new MyService(); 11 | 12 | 13 | @Test 14 | void getUnmodifiableListByCollector() { 15 | List result = myService.getUnmodifiableListByCollector(); 16 | 17 | assertThrows(UnsupportedOperationException.class, () -> { 18 | result.add(5); 19 | }); 20 | } 21 | 22 | @Test 23 | void getUnmodifiableListByCopy() { 24 | List result = myService.getUnmodifiableListByCopy(); 25 | 26 | assertThrows(UnsupportedOperationException.class, () -> { 27 | result.add(5); 28 | }); 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /amber/src/test/java/com/example/var/StudentTest.java: -------------------------------------------------------------------------------- 1 | package com.example.var; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.math.BigDecimal; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | 11 | public class StudentTest { 12 | 13 | Student sut = new Student(new Integer[]{2, 2, 3, 3, 3, 4, 4}); 14 | 15 | @Test 16 | void shouldGetNumberOfMarks() { 17 | Integer result = sut.getNumberOfMarks(); 18 | 19 | assertEquals(7, result); 20 | } 21 | 22 | @Test 23 | void shouldGetTotalSumOfMarks() { 24 | Integer result = sut.getTotalSumOfMarks(); 25 | 26 | assertEquals(21, result); 27 | } 28 | 29 | @Test 30 | void shouldGetAverageOfMarks() { 31 | BigDecimal result = sut.getAverageOfMarks(); 32 | 33 | assertEquals(3, result.intValue()); 34 | } 35 | 36 | @Test 37 | void shouldGetMaximumMark() { 38 | Integer result = sut.getMaximumMark(); 39 | assertEquals(4, result.intValue()); 40 | } 41 | 42 | @Test 43 | void shouldGetMinimumMark() { 44 | Integer result = sut.getMinimumMark(); 45 | 46 | assertEquals(2, result.intValue()); 47 | } 48 | 49 | @Test 50 | void shouldGetDistinctMarks() { 51 | List result = sut.getDistinctMarks(); 52 | 53 | assertEquals(Arrays.asList(2, 3, 4), result); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /amber/tmp/java-versions-cheat-sheet-happycoders.eu-v22.0.3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzpj/pl-java2024/b3607327e97ffb15868a519cb595df959329c5f8/amber/tmp/java-versions-cheat-sheet-happycoders.eu-v22.0.3.pdf -------------------------------------------------------------------------------- /bdd/.gitignore: -------------------------------------------------------------------------------- 1 | # Maven 2 | target/ 3 | 4 | # Ignore Gradle GUI config 5 | gradle-app.setting 6 | 7 | # Eclipse 8 | /.classpath 9 | /.settings/ 10 | /.project 11 | /bin/ 12 | 13 | # IntelliJ 14 | .idea 15 | *.iml 16 | *.ipr 17 | *.iws 18 | 19 | # Misc 20 | *.log 21 | -------------------------------------------------------------------------------- /bdd/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzpj/pl-java2024/b3607327e97ffb15868a519cb595df959329c5f8/bdd/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /bdd/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip -------------------------------------------------------------------------------- /bdd/docs/bdd-vs-tdd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzpj/pl-java2024/b3607327e97ffb15868a519cb595df959329c5f8/bdd/docs/bdd-vs-tdd.png -------------------------------------------------------------------------------- /bdd/docs/bdd.md: -------------------------------------------------------------------------------- 1 | # Behaviour Driven Development 2 | 3 | ## Definicja 4 | * Behavior-Driven Development (BDD) polega na tworzeniu oprogramowania poprzez opisywanie pewnego zachowania z perspektywy jego użytkowników 5 | * BDD to proces wytwarzania oprogramowania, w którym dokumentacja i testy są pisane w języku naturalnym. Jest integralną częścią całego cyklu wytwarzania oprogramowania. 6 | * Funkcjonalność oprogramowania powinna być opisana w języku **Gherkin** jeszcze na etapie zbierania wymagań i analizy, a następnie wykorzystywana w fazie projektowania i implementacji. 7 | 8 | # TDD vs BDD 9 | * w TDD rozwój oprogramowania opiera się tu na testach napisanych dla jeszcze nieistniejących funkcjonalności, podczas gdy BDD ma na celu wykorzystanie zrozumiałego 10 | dla wszystkich nawet osób bez wiedzy technicznej języka 11 | * TDD jest dla dewelopera, BDD dla klienta (i/lub analityka, product owner'a) 12 | ![bdd-vs-tdd](bdd-vs-tdd.png) 13 | 14 | 15 | ## Idealny scenariusz współpracy analityka biznesowego oraz dewelopera i/lub testera 16 | Rozpoczynając testy manualne, tester opiera się na istniejącej dokumentacji, która w jasny sposób pokazuje mu warunki początkowe, wszystkie niezbędne akcje i ich finał. 17 | Następnie na jej podstawie tworzone są testy automatyczne z zachowaniem języka naturalnego. Tester lub deweloper otrzymuje zadanie do przetestowania manualnego/napisania 18 | testu automatycznego i dzięki czytelnej formie zapisu wie, czym ma się zająć. W teorii, interpretacja zadania nie powinna być problemem. 19 | 20 | ## Zalety BDD 21 | Odpowiednio skonstruowana dokumentacja: 22 | 23 | ````gherkin 24 | Scenario: User add article 25 | Given User is logged in 26 | When User add new article 27 | Then Article should be displayed 28 | ```` 29 | wykorzystująca język naturalny, dostępna dla wszystkich członków projektu, może wspierając rozwój aplikacji na różnych etapach. 30 | Można omawiać ją na spotkaniach przed implementacją oraz w jej trakcie, a następnie wykorzystać w testach automatycznych i raportach. 31 | Jest przydatna dla osób bez wiedzy technicznej (np. osoba z biznesu), którzy mają wgląd czy zadane ścieżki biznesowe są pokryte przez testy automatyczne, a rozwój aplikacji idzie w dobrą stronę. 32 | 33 | [![Z przymrużeniem oka...](https://img.youtube.com/vi/fX2altB4AME/default.jpg)](https://youtu.be/fX2altB4AME) 34 | 35 | ## Wady i błędy w wykorzystaniu BDD 36 | * Biznes nie dostarcza gotowych scenariuszy w formie „Given, When, Then” 37 | * Scenariusz testów jest tworzony po czasie 38 | * Biznes nie jest zainteresowany treścią testów 39 | 40 | ## Linki 41 | * [Cucumber](https://cucumber.io/docs/cucumber/) 42 | -------------------------------------------------------------------------------- /bdd/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /bdd/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.example 7 | unit-and-bdd 8 | 1.0-SNAPSHOT 9 | 10 | 11 | UTF-8 12 | 17 13 | 5.9.2 14 | 3.9.0 15 | 3.0.0-M8 16 | 7.11.1 17 | 1.18.26 18 | 19 | 20 | 21 | 22 | 23 | io.cucumber 24 | cucumber-bom 25 | ${cucumber.version} 26 | pom 27 | import 28 | 29 | 30 | org.junit 31 | junit-bom 32 | ${junit.platform.version} 33 | pom 34 | import 35 | 36 | 37 | 38 | 39 | 40 | 41 | io.cucumber 42 | cucumber-java 43 | test 44 | 45 | 46 | io.cucumber 47 | cucumber-junit-platform-engine 48 | test 49 | 50 | 51 | org.junit.platform 52 | junit-platform-suite 53 | test 54 | 55 | 56 | org.junit.jupiter 57 | junit-jupiter 58 | test 59 | 60 | 61 | 62 | org.projectlombok 63 | lombok 64 | ${lombok.version} 65 | provided 66 | 67 | 68 | org.seleniumhq.selenium 69 | selenium-java 70 | 4.8.0 71 | 72 | 73 | 74 | 75 | 76 | 77 | maven-compiler-plugin 78 | ${maven.compiler.plugin.version} 79 | 80 | ${java.version} 81 | ${java.version} 82 | 83 | 84 | 85 | maven-surefire-plugin 86 | ${maven.surefire.plugin.version} 87 | 88 | 89 | **/Test*.java 90 | **/*Test.java 91 | **/*Tests.java 92 | **/*TestCase.java 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /bdd/src/main/java/com/example/FizzBuzzProblem.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | public class FizzBuzzProblem { 4 | 5 | public String getFizzBuzzNumber(int number) { 6 | if (number % 15 == 0) { 7 | return "FizzBuzz"; 8 | } else if (number % 5 == 0) { 9 | return "Buzz"; 10 | } else if (number % 3 == 0) { 11 | return "Fizz"; 12 | } 13 | return String.valueOf(number); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /bdd/src/main/java/com/example/MyStack.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import java.util.*; 4 | 5 | public class MyStack { 6 | 7 | private Deque stack; 8 | 9 | public MyStack() { 10 | this.stack = new ArrayDeque<>(); 11 | } 12 | 13 | public void push(T t) { 14 | stack.push(t); 15 | } 16 | 17 | public T pop() { 18 | return stack.pop(); 19 | } 20 | 21 | public T top() { 22 | return stack.peek(); 23 | } 24 | 25 | public int size() { 26 | return stack.size(); 27 | } 28 | 29 | public boolean isEmpty() { 30 | return size() == 0; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /bdd/src/test/java/com/example/bdd/DatatableExamplStepDefinitions.java: -------------------------------------------------------------------------------- 1 | package com.example.bdd; 2 | 3 | import io.cucumber.datatable.*; 4 | import io.cucumber.java.DataTableType; 5 | import io.cucumber.java.en.*; 6 | 7 | import java.time.*; 8 | import java.time.format.*; 9 | import java.util.*; 10 | import java.util.regex.*; 11 | 12 | import static org.junit.jupiter.api.Assertions.*; 13 | 14 | public class DatatableExamplStepDefinitions { 15 | 16 | List userInfos; 17 | 18 | @Given("user info data table") 19 | public void userInfoDataTable(List userInfos) { 20 | // List> lists = dataTable.asLists(); 21 | // List> maps = dataTable.asMaps(); 22 | this.userInfos = userInfos; 23 | } 24 | 25 | record UserInfo( 26 | String username, 27 | String email, 28 | boolean secretPanelAccess, 29 | LocalDate firstLogin, 30 | int priorityLevel 31 | ) { 32 | } 33 | 34 | @DataTableType 35 | public UserInfo userInfoTransform(Map entry) { 36 | return new UserInfo( 37 | entry.get("username"), 38 | entry.get("email"), 39 | Boolean.parseBoolean(entry.get("secret panel access")), 40 | LocalDate.parse(entry.get("first login date"), DateTimeFormatter.ofPattern("dd-MM-yyyy")), 41 | Integer.parseInt(entry.get("priority level")) 42 | ); 43 | } 44 | 45 | @Then("only {int} users {string} and {string} has access to secret panel") 46 | public void onlyUsersAndHasAccessToSecretPanel(int numberOfUsers, String firstUser, String secondUser) { 47 | List list = this.userInfos.stream() 48 | .filter(e -> e.secretPanelAccess) 49 | .map(e -> e.username) 50 | .toList(); 51 | assertEquals(numberOfUsers, list.size()); 52 | assertEquals(list, List.of(firstUser, secondUser)); 53 | } 54 | 55 | @And("{string} has invalid mail") 56 | public void hasInvalidMail(String username) { 57 | 58 | String actual = this.userInfos.stream() 59 | .filter(e -> !isValidEmail(e.email)) 60 | .map(e -> e.username) 61 | .findFirst() 62 | .orElseThrow(() -> new RuntimeException("Not found user")); 63 | assertEquals(username, actual); 64 | 65 | } 66 | 67 | private boolean isValidEmail(String email) { 68 | return Pattern.matches("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$", email); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /bdd/src/test/java/com/example/bdd/ExampleStepDefinitions.java: -------------------------------------------------------------------------------- 1 | package com.example.bdd; 2 | 3 | import io.cucumber.java.en.*; 4 | 5 | public class ExampleStepDefinitions { 6 | 7 | @Given("an example scenario") 8 | public void anExampleScenario() { 9 | } 10 | 11 | @When("all step definitions are implemented") 12 | public void allStepDefinitionsAreImplemented() { 13 | } 14 | 15 | @Then("the scenario passes") 16 | public void theScenarioPasses() { 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /bdd/src/test/java/com/example/bdd/FizzBuzzProblemStepDefinitions.java: -------------------------------------------------------------------------------- 1 | package com.example.bdd; 2 | 3 | import com.example.*; 4 | import io.cucumber.java.en.*; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | public class FizzBuzzProblemStepDefinitions { 9 | FizzBuzzProblem fizzBuzzProblem; 10 | String result; 11 | 12 | @Given("I have set of numbers") 13 | public void iHaveSetOfNumbers() { 14 | fizzBuzzProblem = new FizzBuzzProblem(); 15 | } 16 | 17 | @When("I pass {int} through algorithm") 18 | public void iPassNumberThroughAlgorithm(int number) { 19 | result = fizzBuzzProblem.getFizzBuzzNumber(number); 20 | } 21 | 22 | @Then("I get {string}") 23 | public void iGet(String expectedResult) { 24 | assertEquals(expectedResult, result); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /bdd/src/test/java/com/example/bdd/RunCucumberTest.java: -------------------------------------------------------------------------------- 1 | package com.example.bdd; 2 | 3 | import org.junit.platform.suite.api.ConfigurationParameter; 4 | import org.junit.platform.suite.api.IncludeEngines; 5 | import org.junit.platform.suite.api.SelectClasspathResource; 6 | import org.junit.platform.suite.api.Suite; 7 | 8 | import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME; 9 | 10 | @Suite 11 | @IncludeEngines("cucumber") 12 | @SelectClasspathResource("bdd") 13 | @ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example.bdd") 14 | public class RunCucumberTest { 15 | } 16 | -------------------------------------------------------------------------------- /bdd/src/test/java/com/example/bdd/StackStepDefinition.java: -------------------------------------------------------------------------------- 1 | package com.example.bdd; 2 | 3 | import com.example.*; 4 | import io.cucumber.java.*; 5 | import io.cucumber.java.en.*; 6 | 7 | import java.util.*; 8 | 9 | import static java.lang.Class.*; 10 | import static org.junit.jupiter.api.Assertions.*; 11 | 12 | public class StackStepDefinition { 13 | 14 | MyStack stack; 15 | 16 | @Before 17 | public void init() { 18 | stack = new MyStack<>(); 19 | } 20 | 21 | @Given("empty stack is created") 22 | public void emptyStackIsCreated() { 23 | assertTrue(stack.isEmpty()); 24 | } 25 | 26 | @When("new element is added to stack") 27 | public void newElementIsAddedToStack() { 28 | stack.push("sss"); 29 | } 30 | 31 | @Then("new element is at the top of the stack") 32 | public void newElementIsAtTheTopOfTheStack() { 33 | assertEquals("sss", stack.top()); 34 | } 35 | 36 | @Given("non-empty stack with {int} elements") 37 | public void nonEmptyStackWithElements(int size) { 38 | stack = new MyStack<>(); 39 | stack.push("element"); 40 | stack.push("element"); 41 | stack.push("element"); 42 | assertEquals(size, stack.size()); 43 | } 44 | 45 | @When("all elements are removed from stack") 46 | public void allElementsAreRemovedFromStack() { 47 | stack.pop(); 48 | stack.pop(); 49 | stack.pop(); 50 | } 51 | 52 | @Then("stack is empty") 53 | public void stackIsEmpty() { 54 | assertTrue(stack.isEmpty()); 55 | } 56 | 57 | @And("throws {string} for getting element from empty stack") 58 | public void throwsForGettingElementFromEmptyStack(String clazz) throws ClassNotFoundException { 59 | NoSuchElementException noSuchElementException = assertThrows(NoSuchElementException.class, () -> stack.pop()); 60 | assertEquals(noSuchElementException.getClass(), forName(clazz)); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /bdd/src/test/resources/bdd/datatable.feature: -------------------------------------------------------------------------------- 1 | Feature: Datatable 2 | 3 | Scenario: Example with data table 4 | Given user info data table 5 | | username | email | secret panel access | first login date | priority level | 6 | | admin | admin@validmail.pl | true | 01-01-1970 | 10 | 7 | | moderator | mod@validmail.pl | true | 01-01-2000 | 8 | 8 | | regular_user | franek@p.lodz.pl | false | 01-02-2010 | 5 | 9 | | different_user | adam@p.lodz.pl | false | 01-02-2010 | 4 | 10 | | blocked_user | ban@validmai | false | 01-02-2005 | -1 | 11 | Then only 2 users "admin" and "moderator" has access to secret panel 12 | And "blocked_user" has invalid mail -------------------------------------------------------------------------------- /bdd/src/test/resources/bdd/example.feature: -------------------------------------------------------------------------------- 1 | Feature: An example 2 | 3 | Scenario: The example 4 | Given an example scenario 5 | When all step definitions are implemented 6 | Then the scenario passes -------------------------------------------------------------------------------- /bdd/src/test/resources/bdd/fizzbuzzproblem.feature: -------------------------------------------------------------------------------- 1 | Feature: FizzBuzzProblem 2 | 3 | Scenario Outline: Solve Fizz Buzz Problem 4 | Given I have set of numbers 5 | When I pass through algorithm 6 | Then I get "" 7 | 8 | Examples: 9 | | number | answer | 10 | | 3 | Fizz | 11 | | 4 | 4 | 12 | | 5 | Buzz | 13 | | 15 | FizzBuzz | 14 | 15 | -------------------------------------------------------------------------------- /bdd/src/test/resources/bdd/stack.feature: -------------------------------------------------------------------------------- 1 | Feature: Test stack features 2 | 3 | Scenario: Adding element to new stack 4 | Given empty stack is created 5 | When new element is added to stack 6 | Then new element is at the top of the stack 7 | 8 | Scenario: Removing elements from the stack 9 | Given non-empty stack with 3 elements 10 | When all elements are removed from stack 11 | Then stack is empty 12 | And throws "java.util.NoSuchElementException" for getting element from empty stack -------------------------------------------------------------------------------- /clean-code/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /.idea/ 3 | /clean_code_solid.iml 4 | /~$ZZPJ2023-clean_code_solid.pptx 5 | /*.pptx -------------------------------------------------------------------------------- /clean-code/README.md: -------------------------------------------------------------------------------- 1 | # Clean Code 2 | 3 | **Zadanie 1:** Clean Code 4 | 5 | Klasa `pl.zzpj.cleancode.doIt` nie przestrzega zasad Clean Code. Przerefaktoruj kod zgodnie z zasadami poznanymi podczas prezentacji. 6 | 7 | Pytania pomocnicze: 8 | - Jaka jest rola tej klasy? 9 | - Jaką funkcjonalność realizuje? 10 | - Jaki jest najlepszy sposób na sprawdzenie poprawności implementacji kolejnych metod tej klasy? 11 | - Czy wszystkie metody są zaimplementowane poprawnie? 12 | --- 13 | 14 | **Zadanie 2:** Single Responsibility Principle 15 | 16 | Reprezentacja modelu ksiązki oraz możliwość jej drukowania (czytania) powinna być odseparowana. Dostarcz oddzielne implementacje modelu książki oraz 17 | jej drukowania zgodnie z Single Responsibility Principle. 18 | 19 | Pakiet, w którym należy umieścić rozwiązanie: `pl.zzpj.solid.srp.book.solution` 20 | 21 | --- 22 | 23 | **Zadanie 3:** Open-closed principle 24 | 25 | Limity prędkości i kary za jej przekroczenie są różne dla każdego z 50 stanów USA. Należy dostarczyć łatwo rozszerzalną implementację, w której każdy 26 | stan będzie mógł zdefiniować swoje kary. Na chwilę obecną załóżmy, że będą to 3 stany USA, które skorzystają z naszego API, ale niewykluczone, że w 27 | przyszłości inne stany również decydują się je wykorzystać. 28 | 29 | Pakiet, w którym należy umieścić rozwiązanie: `pl.zzpj.solid.ocp.usa.solution` 30 | 31 | --- 32 | 33 | **Zadanie 4:** Liscov Substitution Principle 34 | 35 | Podstawowym przykładem obrazującym zasadę Barbary Liskov jest zbudowanie aplikacji, która będzie korzystała z własności podstawowych figur geometrycznych: 36 | kwadrat, prostokąt, koło... wraz z obliczaniem ich obwodu oraz pola powierzchni. Czy z punktu widzenia programisty i programowania obiektowego 37 | kwadrat jest prostokątem? 38 | 39 | Pakiet w którym należy dostarczyć rozwiązanie: `pl.zzpj.solid.lsp.shape` 40 | 41 | --- 42 | 43 | **Zadanie 5:** Interface Separation Principle 44 | 45 | Klasa `Contact` ma dwie własności, jedna z nich przedstawia możliwość kontaktowania się przez wiadomość email, a druga to kontakt telefoniczny. 46 | Zaleca się wyróżnienie tych własności za pomocą interfejsów. Interfejsy powinny deklarować metody charakterystyczne dla danej własności. 47 | 48 | Pakiet, w którym należy dostarczyć rozwiązanie: `pl.zzpj.solid.isp.contactbook.solution` 49 | 50 | --- 51 | 52 | **Zadanie 6:** Dependency Inversion Principle 53 | 54 | Mamy serwis informujący o zmianach pogodowych. Informacje o zmianach wysyłane są na różne urządzenia: telefony lub skrzynki poczty elektronicznej. Oba te urządzenia łączy jedna wspólna cecha jaką jest odbiór wiadomości i jej wyświetlenie. Telefon i skrzynka są modułami niskopoziomowymi, natomiast "Tracker" jest modułem wysokopoziomowym, który nie powinien zależeć od modułów niskopoziomowych. 55 | 56 | Pakiet, w którym należy dostarczyć rozwiązanie: `pl.zzpj.solid.dip.weathertracker.solution` -------------------------------------------------------------------------------- /clean-code/ZZPJ2024-clean_code_solid.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzpj/pl-java2024/b3607327e97ffb15868a519cb595df959329c5f8/clean-code/ZZPJ2024-clean_code_solid.pdf -------------------------------------------------------------------------------- /clean-code/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | pl.zzpj 5 | clean_code_solid 6 | 0.0.1-SNAPSHOT 7 | 8 | clean code and solid 9 | clean code and solid 10 | 11 | 21 12 | 21 13 | 14 | 15 | 16 | 17 | 18 | org.apache.maven.plugins 19 | maven-compiler-plugin 20 | 3.8.0 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/cleancode/doit.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.cleancode; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Map.Entry; 7 | 8 | public class doit { 9 | 10 | Map __1 = new HashMap(); 11 | private int _2 = Integer.MIN_VALUE;private int kpp = Integer.MAX_VALUE; 12 | 13 | public doit(List i1) { 14 | p(i1); 15 | } 16 | 17 | public doit() { 18 | 19 | /*Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla molestie lacus at diam congue fermentum. Phasellus id facilisis dolor. Maecenas neque purus, 20 | tempus id scelerisque nec, facilisis eget nunc. Praesent ante dolor, maximus et porta ac, finibus vel erat. Donec diam orci, bibendum eu odio ut, auctor fringilla justo. 21 | // Nam sit amet ante tempus, varius nisi id, porttitor mauris. Suspendisse vitae vulputate ipsum. 22 | // 23 | //Quisque malesuada lacus nec arcu posuere facilisis. Praesent vel vulputate metus. Vestibulum ac maximus magna. Aliquam lacinia iaculis erat, ac ullamcorper lectus cursus vel. 24 | //Vivamus id pulvinar risus. Sed in nunc volutpat, sollicitudin lectus a, faucibus magna. Sed maximus fringilla nibh id porttitor. Quisque dignissim, leo ut consectetur hendrerit, ex 25 | //elit feugiat nisi, nec elementum elit felis id dolor. Maecenas lacinia consequat lacus. Nulla vitae erat a justo pellentesque eleifend id nec massa. Morbi feugiat ut erat ac placerat. 26 | //Nulla lorem metus, placerat quis blandit in, aliquet ac ipsum. Etiam ut arcu sem. Aliquam erat volutpat. 27 | // 28 | //Quisque tellus dui, semper efficitur efficitur ut, accumsan sed nulla. Nullam sed orci placerat, auctor est sed, venenatis felis. In vulputate mollis ante, sed 29 | //tincidunt nisi maximus nec. Nunc id purus non lacus rutrum pharetra non ut libero. Integer id tellus in dolor feugiat iaculis. Phasellus id magna id augue tempus p 30 | //orta in quis justo. Curabitur eleifend id sem ac faucibus. Vivamus consequat ac enim at dapibus. Cras in volutpat dolor. Pellentesque viverra, metus ac consectetur congue, mi ligula 31 | // vestibulum mi, ut sagittis augue justo eget dolor. Vivamus sit amet pharetra leo. 32 | // 33 | //Vestibulum consectetur nunc metus, lobortis dapibus lacus porta in. Morbi et metus massa. Donec cursus efficitur massa, non egestas ante convallis et. Aliquam matti 34 | //s arcu in felis rutrum vehicula. Nunc aliquam nulla sit amet vestibulum tincidunt. Maecenas ultricies augue ut nisi blandit vestibulum. Nunc finibus at quam a tincidunt. Nam 35 | //tristique nisl eget lacus dapibus, eleifend fermentum risus facilisis. Integer viverra eros eget mi ultricies consequat. 36 | // 37 | //Phasellus mattis commodo magna, id semper sapien suscipit a. Vivamus ut condimentum mauris. Praesent aliquet erat fringilla velit finibus porta. In molestie lacus 38 | //elementum eros tempus, et lacinia magna interdum. Suspendisse mattis vehicula elit, a consequat lorem accumsan sit amet. Vivamus molestie lectus et lacus pharetra, ut 39 | //pulvinar est laoreet. Vivamus hendrerit pellentesque blandit. Curabitur sed dolor iaculis, sodales nisl id, tempor metus. Vivamus erat sem, iaculis vitae risus sed, eleifend luctus velit. 40 | */ 41 | } 42 | 43 | public void p(List l1) { int i = 0;for (; i < l1.size(); i++) { p(l1.get(i)); }} 44 | 45 | public void p(Integer i) { 46 | if (__1.containsKey(i)) { 47 | Integer k = __1.get(i); 48 | __1.put(i, k +1); 49 | } else { 50 | __1.put(1, 1); 51 | } 52 | 53 | if (i > _2) { 54 | _2 = i; 55 | } 56 | 57 | if (i < kpp) { 58 | kpp = i; 59 | } 60 | } 61 | 62 | public int DOIT(int i) { if (__1.containsKey(i)) { return __1.get(i); 63 | } else { return 0; 64 | } } 65 | 66 | public double dasIstGut() { 67 | double jk = 0;double p = 0; 68 | for (Entry u : __1.entrySet()) { 69 | p += u.getValue();jk += u.getKey() * u.getValue(); 70 | }return jk/p; 71 | } 72 | 73 | public int l1() { 74 | return _2; 75 | } 76 | 77 | public int l2() { 78 | return kpp; 79 | } 80 | 81 | 82 | //TODO: future use when i will know what my name and number are 83 | public String getFizzBuzzNumber(int number) { 84 | //TODO: implement 85 | //Das Belvedere ist ein Barock-Palast. 86 | //Heute ist es ein Museum. 87 | //Die Menschen fotografieren oft das Belvedere. 88 | //Das Museum ist interessant, aber es gibt auch einen schönen Garten. 89 | return null; 90 | } 91 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/dip/driver/solution/Driver.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.dip.driver.solution; 2 | 3 | public class Driver { 4 | 5 | private Vehicle vehicle; 6 | 7 | public Driver(final Vehicle vehicle){ 8 | this.vehicle = vehicle; 9 | } 10 | 11 | public void increaseSpeed(){ 12 | vehicle.accelerate(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/dip/driver/solution/RacingCar.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.dip.driver.solution; 2 | 3 | public class RacingCar implements Vehicle{ 4 | 5 | private final int maxFuel; 6 | private int remainingFuel; 7 | private int power; 8 | 9 | public RacingCar(final int maxFuel) { 10 | this.maxFuel = maxFuel; 11 | remainingFuel = maxFuel; 12 | } 13 | 14 | @Override 15 | public void accelerate() { 16 | power++; 17 | remainingFuel--; 18 | } 19 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/dip/driver/solution/Vehicle.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.dip.driver.solution; 2 | 3 | public interface Vehicle { 4 | 5 | void accelerate(); 6 | 7 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/dip/driver/violation/Driver.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.dip.driver.violation; 2 | 3 | public class Driver { 4 | 5 | private RacingCar vehicle; 6 | 7 | public Driver(){ 8 | this.vehicle = new RacingCar(100); 9 | } 10 | 11 | public void increaseSpeed(){ 12 | vehicle.accelerate(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/dip/driver/violation/LimousineCar.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.dip.driver.violation; 2 | 3 | public class LimousineCar { 4 | 5 | private final int maxFuel; 6 | private int remainingFuel; 7 | private int power; 8 | 9 | public LimousineCar(final int maxFuel) { 10 | this.maxFuel = maxFuel; 11 | remainingFuel = maxFuel; 12 | } 13 | 14 | public void accelerate(){ 15 | power++; 16 | remainingFuel--; 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/dip/driver/violation/RacingCar.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.dip.driver.violation; 2 | 3 | public class RacingCar { 4 | 5 | private final int maxFuel; 6 | private int remainingFuel; 7 | private int power; 8 | 9 | public RacingCar(final int maxFuel) { 10 | this.maxFuel = maxFuel; 11 | remainingFuel = maxFuel; 12 | } 13 | 14 | public void accelerate(){ 15 | power++; 16 | remainingFuel--; 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/dip/weathertracker/solution/TODO.txt: -------------------------------------------------------------------------------- 1 | Mamy serwis informujący o zmianach pogodowych. Informacje o zmianach wysyłane są na różne urząrzenia: telefony 2 | lub skrzynki poczty elekronicznej. Oba te urządzenia łączy jedna wspólna cecha jaką jest odbiór wiadomości i jej 3 | wyświetlenie. Telefon i skrzynka są modułami niskopoziomowymi, natomiast "Tracker" jest modułem wysokopoziomowym, 4 | który nie powinien zależeć od modułów niskopoziomowych. -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/dip/weathertracker/violation/Emailer.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.dip.weathertracker.violation; 2 | 3 | 4 | public class Emailer { 5 | public String generateWeatherAlert(String weatherConditions) { 6 | String alert = "It is " + weatherConditions; 7 | return alert; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/dip/weathertracker/violation/Phone.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.dip.weathertracker.violation; 2 | 3 | public class Phone { 4 | public String generateWeatherAlert(String weatherConditions) { 5 | String alert = "It is " + weatherConditions; 6 | return alert; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/dip/weathertracker/violation/WeatherTracker.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.dip.weathertracker.violation; 2 | 3 | 4 | public class WeatherTracker { 5 | String currentConditions; 6 | Phone phone; 7 | Emailer emailer; 8 | 9 | public WeatherTracker() { 10 | phone = new Phone(); // BAD 11 | emailer = new Emailer(); // BAD 12 | } 13 | 14 | public void setCurrentConditions(String weatherDescription) { 15 | this.currentConditions = weatherDescription; 16 | if (weatherDescription == "rainy") { 17 | String alert = phone.generateWeatherAlert(weatherDescription); 18 | System.out.print(alert); 19 | } 20 | if (weatherDescription == "sunny") { 21 | String alert = emailer.generateWeatherAlert(weatherDescription); 22 | System.out.print(alert); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/contactbook/solution/TODO.txt: -------------------------------------------------------------------------------- 1 | Klasa Contact ma dwie własności, jedna z nich przedstawia możliwośc kontaktowania się przez wiadomość email, 2 | a druga to kontakt telefoniczny. Zaleca się wyróżnienie tych własności za pomocą interfejsów. 3 | Te interfejsy deklarują metody charakterystyczne dla danej własności -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/contactbook/violation/Contact.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.contactbook.violation; 2 | 3 | class Contact { 4 | public String name; 5 | public String address; 6 | public String emailAddress; 7 | public String telephone; 8 | 9 | public Contact(String name, String address, String emailAddress, 10 | String telephone) { 11 | super(); 12 | this.name = name; 13 | this.address = address; 14 | this.emailAddress = emailAddress; 15 | this.telephone = telephone; 16 | } 17 | public String getName() { 18 | return name; 19 | } 20 | public void setName(String name) { 21 | this.name = name; 22 | } 23 | public String getAddress() { 24 | return address; 25 | } 26 | public void setAddress(String address) { 27 | this.address = address; 28 | } 29 | public String getEmailAddress() { 30 | return emailAddress; 31 | } 32 | public void setEmailAddress(String emailAddress) { 33 | this.emailAddress = emailAddress; 34 | } 35 | public String getTelephone() { 36 | return telephone; 37 | } 38 | public void setTelephone(String telephone) { 39 | this.telephone = telephone; 40 | } 41 | 42 | 43 | } 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/contactbook/violation/Dialler.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.contactbook.violation; 2 | 3 | class Dialler { 4 | 5 | public void makeCall(Contact dialable) { 6 | 7 | String telephone = dialable.getTelephone(); 8 | 9 | // call using telephone 10 | } 11 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/contactbook/violation/Emailer.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.contactbook.violation; 2 | 3 | class Emailer { 4 | 5 | 6 | public void sendMessage(Contact emailable, String subject, String body) { 7 | 8 | String emailAddress = emailable.getEmailAddress(); 9 | 10 | sendEmail(emailAddress, subject, body); 11 | } 12 | 13 | 14 | 15 | 16 | 17 | private void sendEmail(String emailAddress, String subject, String body) { 18 | // TODO Auto-generated method stub 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/contactbook/violation/InterfaceSegregationPrincipleBAD.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.contactbook.violation; 2 | 3 | class InterfaceSegregationPrincipleBAD { 4 | 5 | Emailer emailer; 6 | Dialler dialler; 7 | 8 | public InterfaceSegregationPrincipleBAD() { 9 | emailer = new Emailer(); 10 | dialler = new Dialler(); 11 | } 12 | 13 | public static void main(String[] args) { 14 | 15 | InterfaceSegregationPrincipleBAD interfaceSegregationPrinciple = new InterfaceSegregationPrincipleBAD(); 16 | interfaceSegregationPrinciple.contactPeople(); 17 | 18 | } 19 | 20 | public void contactPeople() { 21 | 22 | Contact contact = new Contact("Jan Kowalski", "Kielce", "jan.kowalski@gmail.com", "83744-23434"); 23 | emailer.sendMessage(contact, "promocja", "tanio dzisiaj!"); 24 | dialler.makeCall(contact); 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/switcher/solution/CameraSwitch.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.switcher.solution; 2 | 3 | 4 | public interface CameraSwitch { 5 | 6 | void turnCameraOn(); 7 | 8 | void turnCameraOff(); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/switcher/solution/Car.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.switcher.solution; 2 | 3 | 4 | public class Car extends Vehicle implements RadioSwitch { 5 | 6 | private boolean radioOn; 7 | 8 | public boolean isRadioOn() { 9 | return radioOn; 10 | } 11 | 12 | @Override 13 | public void turnRadioOn() { 14 | radioOn = true; 15 | } 16 | 17 | @Override 18 | public void turnRadioOff() { 19 | radioOn = false; 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/switcher/solution/Drone.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.switcher.solution; 2 | 3 | 4 | public class Drone extends Vehicle implements CameraSwitch { 5 | 6 | private boolean cameraOn; 7 | 8 | public boolean isCameraOn() { 9 | return cameraOn; 10 | } 11 | 12 | @Override 13 | public void turnCameraOn() { 14 | cameraOn = true; 15 | } 16 | 17 | @Override 18 | public void turnCameraOff() { 19 | cameraOn = false; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/switcher/solution/EngineSwitch.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.switcher.solution; 2 | 3 | public interface EngineSwitch { 4 | 5 | void startEngine(); 6 | 7 | void shutDownEngine(); 8 | 9 | } 10 | 11 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/switcher/solution/RadioSwitch.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.switcher.solution; 2 | 3 | public interface RadioSwitch { 4 | 5 | void turnRadioOn(); 6 | 7 | void turnRadioOff(); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/switcher/solution/Vehicle.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.switcher.solution; 2 | 3 | public abstract class Vehicle implements EngineSwitch { 4 | 5 | private boolean engineRunning; 6 | 7 | public boolean isEngineRunning() { 8 | return engineRunning; 9 | } 10 | 11 | @Override 12 | public void startEngine() { 13 | engineRunning = true; 14 | } 15 | 16 | @Override 17 | public void shutDownEngine() { 18 | engineRunning = false; 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/switcher/violation/Car.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.switcher.violation; 2 | 3 | public class Car extends Vehicle { 4 | 5 | private boolean radioOn; 6 | 7 | public boolean isRadioOn() { 8 | return radioOn; 9 | } 10 | 11 | @Override 12 | public void turnRadioOn() { 13 | radioOn = true; 14 | } 15 | 16 | @Override 17 | public void turnRadioOff() { 18 | radioOn = false; 19 | } 20 | 21 | @Override 22 | public void turnCameraOn() { 23 | // nothing to do here 24 | } 25 | 26 | @Override 27 | public void turnCameraOff() { 28 | // nothing to do here 29 | } 30 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/switcher/violation/Drone.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.switcher.violation; 2 | 3 | public class Drone extends Vehicle { 4 | 5 | private boolean cameraOn; 6 | 7 | public boolean isCameraOn() { 8 | return cameraOn; 9 | } 10 | 11 | @Override 12 | public void turnCameraOn() { 13 | cameraOn = true; 14 | } 15 | 16 | @Override 17 | public void turnCameraOff() { 18 | cameraOn = false; 19 | } 20 | 21 | @Override 22 | public void turnRadioOn() { 23 | // nothing to do here 24 | } 25 | 26 | @Override 27 | public void turnRadioOff() { 28 | // nothing to do here 29 | } 30 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/switcher/violation/Switches.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.switcher.violation; 2 | 3 | public interface Switches { 4 | 5 | void startEngine(); 6 | 7 | void shutDownEngine(); 8 | 9 | void turnRadioOn(); 10 | 11 | void turnRadioOff(); 12 | 13 | void turnCameraOn(); 14 | 15 | void turnCameraOff(); 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/isp/switcher/violation/Vehicle.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.isp.switcher.violation; 2 | 3 | public abstract class Vehicle implements Switches { 4 | 5 | private boolean engineRunning; 6 | 7 | public boolean isEngineRunning() { 8 | return engineRunning; 9 | } 10 | 11 | @Override 12 | public void startEngine() { 13 | engineRunning = true; 14 | } 15 | 16 | @Override 17 | public void shutDownEngine() { 18 | engineRunning = false; 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/lsp/shape/TODO.txt: -------------------------------------------------------------------------------- 1 | Podstawowym przykładem obrazującym zasadę Barbary Liskov jest zbudowanie aplikacji, która będzie obrazowała 2 | podstawowe figury geometryczne: kwadrat, prostokąd, koło... wraz z obliczaniem ich obwodu oraz pola powierzchni. 3 | Czy z punktu widzenia programisty i programowania obiektowego kwadrat jest prostokątem? -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/lsp/vehiclemovement/solution/Car.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.lsp.vehiclemovement.solution; 2 | 3 | public class Car extends Vehicle { 4 | 5 | @Override 6 | public void changeGear(Gear gear) { 7 | Gear actualGear = getGear(); 8 | if (isMovingForwards(gear, actualGear) 9 | || isMovingBackwards(gear, actualGear)) { 10 | stop(); 11 | } 12 | super.changeGear(gear); 13 | } 14 | 15 | private boolean isMovingBackwards(Gear gear, Gear actualGear) { 16 | return isMoving() && Gear.R.equals(actualGear) && Gear.D.equals(gear); 17 | } 18 | 19 | private boolean isMovingForwards(Gear gear, Gear actualGear) { 20 | return isMoving() && Gear.D.equals(actualGear) && Gear.R.equals(gear); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/lsp/vehiclemovement/solution/Gear.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.lsp.vehiclemovement.solution; 2 | 3 | public enum Gear { 4 | P, // Parking 5 | R, // Reverse 6 | N, // Neutral 7 | D // Drive 8 | } 9 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/lsp/vehiclemovement/solution/Plane.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.lsp.vehiclemovement.solution; 2 | 3 | public class Plane extends Vehicle { 4 | 5 | // A plane can reverse engine gear while moving forward, no problem here 6 | } 7 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/lsp/vehiclemovement/solution/Vehicle.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.lsp.vehiclemovement.solution; 2 | 3 | public class Vehicle { 4 | 5 | private boolean isMoving; 6 | private Gear gear; 7 | 8 | public void move(){ 9 | isMoving = true; 10 | } 11 | 12 | public void stop(){ 13 | isMoving = false; 14 | } 15 | 16 | public boolean isMoving() { 17 | return isMoving; 18 | } 19 | 20 | public Gear getGear() { 21 | return gear; 22 | } 23 | 24 | public void changeGear(final Gear gear) { 25 | this.gear = gear; 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/lsp/vehiclemovement/violation/Car.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.lsp.vehiclemovement.violation; 2 | 3 | public class Car extends Vehicle { 4 | 5 | @Override 6 | public void changeGear(Gear gear) { 7 | if(Gear.R.equals(gear) && getGear().equals(Gear.D)){ 8 | throw new RuntimeException("Can't change to REVERSE gear when " + getGear().toString() + " gear is engaged!"); 9 | } 10 | super.changeGear(gear); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/lsp/vehiclemovement/violation/Gear.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.lsp.vehiclemovement.violation; 2 | 3 | public enum Gear { 4 | P, // Parking 5 | R, // Reverse 6 | N, // Neutral 7 | D // Drive 8 | } 9 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/lsp/vehiclemovement/violation/Plane.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.lsp.vehiclemovement.violation; 2 | 3 | public class Plane extends Vehicle { 4 | 5 | // A plane can reverse engine gear while moving forward, no problem here 6 | } 7 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/lsp/vehiclemovement/violation/Vehicle.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.lsp.vehiclemovement.violation; 2 | 3 | public class Vehicle { 4 | 5 | private Gear gear; 6 | 7 | public Gear getGear() { 8 | return gear; 9 | } 10 | 11 | public void changeGear(final Gear gear) { 12 | this.gear = gear; 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/greeter/solution/CasualPersonality.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.greeter.solution; 2 | 3 | public class CasualPersonality implements Personality { 4 | public String greet() { 5 | return "Sup bro?"; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/greeter/solution/FormalPersonality.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.greeter.solution; 2 | 3 | 4 | public class FormalPersonality implements Personality { 5 | public String greet() { 6 | return "Good evening, sir."; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/greeter/solution/Greeter.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.greeter.solution; 2 | 3 | 4 | public class Greeter { 5 | private Personality personality; 6 | 7 | public Greeter(Personality personality) { 8 | this.personality = personality; 9 | } 10 | 11 | public String greet() { 12 | return this.personality.greet(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/greeter/solution/IntimatePersonality.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.greeter.solution; 2 | 3 | 4 | public class IntimatePersonality implements Personality { 5 | public String greet() { 6 | return "Hello Darling!"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/greeter/solution/Personality.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.greeter.solution; 2 | 3 | 4 | public interface Personality { 5 | public String greet(); 6 | } 7 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/greeter/violation/Greeter.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.greeter.violation; 2 | 3 | 4 | public class Greeter { 5 | String formality; 6 | 7 | public String greet() { 8 | if (this.formality == "formal") { 9 | return "Good evening, sir."; 10 | } 11 | else if (this.formality == "casual") { 12 | return "Sup bro?"; 13 | } 14 | else if (this.formality == "intimate") { 15 | return "Hello Darling!"; 16 | } 17 | else { 18 | return "Hello."; 19 | } 20 | } 21 | 22 | public void setFormality(String formality) { 23 | this.formality = formality; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/usa/solution/TODO.txt: -------------------------------------------------------------------------------- 1 | Limity prędkości i kary za jej przekroczenie są różne dla każdego z 50 stanów USA. 2 | Należy dostarczyć łatwo rozszerzalną implementację, w której każdy stan będzie mógł zdefiniować swoje kary. 3 | Na chwilę obecną załóżmy, że będą to 3 stany USA, które skorzystają z naszego API, 4 | ale niewykluczone, że w przyszłości inne stany zdecydują się również skorzystać z API. 5 | Dlatego implementacja powinna być otwarta na rozszerzanie bez potrzeby zmieniania istniejącej już implementacji dla 3 stanów. -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/usa/violation/USASpeedLimitFines.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.usa.violation; 2 | 3 | public class USASpeedLimitFines { 4 | 5 | private static final int SC_MAX_SPEED = 0; 6 | private static final int AL_MAX_SPEED = 0; 7 | private static final int GA_MAX_SPEED = 0; 8 | 9 | public double calcualateSpeedLimitFine(String stateCode, int speed) { 10 | 11 | double fine = 0; 12 | switch (stateCode) { 13 | case "SC": { 14 | if (speed > SC_MAX_SPEED) { 15 | // calculate... 16 | } 17 | return fine; 18 | } 19 | case "AL": { 20 | if (speed > AL_MAX_SPEED) { 21 | // calculate... 22 | } 23 | return fine; 24 | } 25 | case "GA": { 26 | if (speed > GA_MAX_SPEED) { 27 | // calculate... 28 | } 29 | return fine; 30 | } 31 | 32 | } 33 | return 0.0; 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/vehicle/solution/Comfort.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.vehicle.solution; 2 | 3 | public class Comfort implements DrivingMode { 4 | 5 | private static final int POWER = 400; 6 | private static final int SUSPENSION_HEIGHT = 20; 7 | 8 | @Override 9 | public int getPower() { 10 | return POWER; 11 | } 12 | 13 | @Override 14 | public int getSuspensionHeight() { 15 | return SUSPENSION_HEIGHT; 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/vehicle/solution/DrivingMode.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.vehicle.solution; 2 | 3 | public interface DrivingMode { 4 | 5 | int getPower(); 6 | int getSuspensionHeight(); 7 | } 8 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/vehicle/solution/Economy.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.vehicle.solution; 2 | 3 | public class Economy implements DrivingMode{ 4 | 5 | private static final int POWER = 300; 6 | private static final int SUSPENSION_HEIGHT = 20; 7 | 8 | @Override 9 | public int getPower() { 10 | return POWER; 11 | } 12 | 13 | @Override 14 | public int getSuspensionHeight() { 15 | return SUSPENSION_HEIGHT; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/vehicle/solution/EventHandler.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.vehicle.solution; 2 | 3 | public class EventHandler { 4 | 5 | private Vehicle vehicle; 6 | 7 | public EventHandler(final Vehicle vehicle) { 8 | this.vehicle = vehicle; 9 | } 10 | 11 | public void changeDrivingMode(final DrivingMode drivingMode){ 12 | vehicle.setPower(drivingMode.getPower()); 13 | vehicle.setSuspensionHeight(drivingMode.getSuspensionHeight()); 14 | // now, when we need to add another mode (e.g. ECONOMY) just create a new class: Economy. 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/vehicle/solution/Sport.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.vehicle.solution; 2 | 3 | public class Sport implements DrivingMode { 4 | 5 | private static final int POWER = 500; 6 | private static final int SUSPENSION_HEIGHT = 10; 7 | 8 | @Override 9 | public int getPower() { 10 | return POWER; 11 | } 12 | 13 | @Override 14 | public int getSuspensionHeight() { 15 | return SUSPENSION_HEIGHT; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/vehicle/solution/Vehicle.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.vehicle.solution; 2 | 3 | public class Vehicle { 4 | 5 | private int power; 6 | private int suspensionHeight; 7 | 8 | public int getPower() { 9 | return power; 10 | } 11 | 12 | public int getSuspensionHeight() { 13 | return suspensionHeight; 14 | } 15 | 16 | public void setPower(final int power) { 17 | this.power = power; 18 | } 19 | 20 | public void setSuspensionHeight(final int suspensionHeight) { 21 | this.suspensionHeight = suspensionHeight; 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/vehicle/violation/DrivingMode.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.vehicle.violation; 2 | 3 | public enum DrivingMode { 4 | SPORT, COMFORT 5 | } 6 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/vehicle/violation/EventHandler.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.vehicle.violation; 2 | 3 | public class EventHandler { 4 | 5 | private Vehicle vehicle; 6 | 7 | public EventHandler(final Vehicle vehicle) { 8 | this.vehicle = vehicle; 9 | } 10 | 11 | public void changeDrivingMode(final DrivingMode drivingMode){ 12 | switch (drivingMode){ 13 | case SPORT: 14 | vehicle.setPower(500); 15 | vehicle.setSuspensionHeight(10); 16 | break; 17 | case COMFORT: 18 | vehicle.setPower(400); 19 | vehicle.setSuspensionHeight(20); 20 | break; 21 | default: 22 | vehicle.setPower(400); 23 | vehicle.setSuspensionHeight(20); 24 | break; 25 | // when we need to add another mode (e.g. ECONOMY) 2 classes will change DrivingMode and EventHandler. 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/ocp/vehicle/violation/Vehicle.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.ocp.vehicle.violation; 2 | 3 | public class Vehicle { 4 | 5 | private int power; 6 | private int suspensionHeight; 7 | 8 | public int getPower() { 9 | return power; 10 | } 11 | 12 | public int getSuspensionHeight() { 13 | return suspensionHeight; 14 | } 15 | 16 | public void setPower(final int power) { 17 | this.power = power; 18 | } 19 | 20 | public void setSuspensionHeight(final int suspensionHeight) { 21 | this.suspensionHeight = suspensionHeight; 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/srp/book/solution/TODO.txt: -------------------------------------------------------------------------------- 1 | Reprezentacja modelu ksiązki oraz możliwość jej drukowania (czytania) powinna być odseparowana. -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/srp/book/violation/BookAndPrinter.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.srp.book.violation; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class BookAndPrinter { 7 | 8 | private int currentPage = 0; 9 | 10 | private Map pages = new HashMap<>(); 11 | 12 | private String libraryRoomName; 13 | private String rowLocator; 14 | private int indexOnShelf; 15 | 16 | public String getTitle() { 17 | return "A Great Book"; 18 | } 19 | 20 | public String getAuthor() { 21 | return "John Doe"; 22 | } 23 | 24 | public String getCurrentPageContents() { 25 | return pages.get(currentPage); 26 | } 27 | 28 | public void turnPage() { 29 | currentPage ++; 30 | } 31 | 32 | /** 33 | * Prints the current page. 34 | */ 35 | public void printCurrentPage() { 36 | System.out.println(pages.get(currentPage)); 37 | } 38 | 39 | /** 40 | * Gives the library name 41 | * 42 | * @return 43 | */ 44 | public String libraryRoomName() { 45 | return libraryRoomName; 46 | } 47 | 48 | /** 49 | * Gives the row location of the book. 50 | * @return 51 | */ 52 | public String getLocationRowLocator() { 53 | return rowLocator; 54 | } 55 | 56 | /** 57 | * Gives the number from shelf. 58 | * @return 59 | */ 60 | public int getIndexOnShelf() { 61 | return indexOnShelf; 62 | } 63 | 64 | /** 65 | * Prints all pages 66 | * @return 67 | */ 68 | public String printAllPages() { 69 | 70 | String allPages = new String(); 71 | for(Map.Entry page : pages.entrySet()) { 72 | allPages += (page.getKey() + " " + page.getValue()); 73 | } 74 | return allPages; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/srp/vehicle/solution/FuelPump.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.srp.vehicle.solution; 2 | 3 | public class FuelPump implements Refualable { 4 | 5 | @Override 6 | public void reFuel(final Vehicle vehicle){ 7 | final int remainingFuel = vehicle.getRemainingFuel(); 8 | final int additionalFuel = vehicle.getMaxFuel() - remainingFuel; 9 | vehicle.setRemainingFuel(remainingFuel + additionalFuel); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/srp/vehicle/solution/Refualable.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.srp.vehicle.solution; 2 | 3 | public interface Refualable { 4 | void reFuel(final Vehicle vehicle); 5 | } 6 | -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/srp/vehicle/solution/Vehicle.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.srp.vehicle.solution; 2 | 3 | public class Vehicle { 4 | 5 | private final int maxFuel; 6 | private int remainingFuel; 7 | 8 | public Vehicle(final int maxFuel) { 9 | this.maxFuel = maxFuel; 10 | this.remainingFuel = maxFuel; 11 | } 12 | 13 | public int getMaxFuel() { 14 | return maxFuel; 15 | } 16 | 17 | public int getRemainingFuel() { 18 | return remainingFuel; 19 | } 20 | 21 | public void setRemainingFuel(final int remainingFuel) { 22 | this.remainingFuel = remainingFuel; 23 | } 24 | 25 | public void accelerate() { 26 | remainingFuel--; 27 | } 28 | } -------------------------------------------------------------------------------- /clean-code/src/main/java/pl/zzpj/solid/srp/vehicle/violation/Vehicle.java: -------------------------------------------------------------------------------- 1 | package pl.zzpj.solid.srp.vehicle.violation; 2 | 3 | public class Vehicle { 4 | 5 | private final int maxFuel; 6 | private int remainingFuel; 7 | 8 | public Vehicle(final int maxFuel) { 9 | this.maxFuel = maxFuel; 10 | remainingFuel = maxFuel; 11 | } 12 | 13 | // this is not a car's responsibility. 14 | public void reFuel(){ 15 | remainingFuel = maxFuel; 16 | } 17 | 18 | public int getMaxFuel() { 19 | return maxFuel; 20 | } 21 | 22 | public int getRemainingFuel() { 23 | return remainingFuel; 24 | } 25 | 26 | public void setRemainingFuel(final int remainingFuel) { 27 | this.remainingFuel = remainingFuel; 28 | } 29 | 30 | public void accelerate() { 31 | remainingFuel--; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /clean-code/src/test/java/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzpj/pl-java2024/b3607327e97ffb15868a519cb595df959329c5f8/clean-code/src/test/java/.keep -------------------------------------------------------------------------------- /intellij/README.md: -------------------------------------------------------------------------------- 1 | Przydatne materiały: 2 | - 3 | 4 | + [Pet Clinic Project](https://github.com/spring-projects/spring-petclinic) 5 | + [IntelliJ IDEA Conf 2024](https://youtu.be/ZD_YxTmQ16Q) 6 | + [IntelliJ IDEA. Debugger Essentials](https://youtu.be/59RC8gVPlvk) 7 | + [IntelliJ IDEA. Debugger Advanced](https://www.youtube.com/watch?v=40Og3hTV--k) 8 | + [IntelliJ IDEA. Debugger Professional](https://youtu.be/JPR3w3Qtwzw) 9 | + [Top 15 IntelliJ IDEA shortcuts](https://youtu.be/QYO5_riePOQ) 10 | + [open-source IntelliJ plugins](https://docs.google.com/spreadsheets/d/1TYXZd68TbuSRYj-9qlP2TBH1fD2nbLK3OGMKKmBBFKs) 11 | + [VIM as Your editor](https://www.youtube.com/playlist?list=PLGC1ANqgjg7m5z41mW-A5b-7CKUeCnWII) 12 | + [IntelliJ Wizardry with Heinz Kabutz 2022 Edition](https://javaspecialists.teachable.com/p/intellij-wizardry-2022) 13 | -------------------------------------------------------------------------------- /intellij/grupy/README.md: -------------------------------------------------------------------------------- 1 | Grupa 1: 2 | 3 | + Sławomir Andrzejczak 242349 4 | + Aneta Malinowska 242463 5 | + Kuba Kowalik 242434 6 | + Filip Szczepanek 242544 7 | + Kacper Jagodziński 242403 8 | 9 | Grupa 2: 10 | + Adam Czerwonka 242374 11 | + Marcel Badek 242352 12 | + Konrad Koza 242436 13 | + Jakub Górski 242396 14 | + Kacper Kafara 242412 15 | 16 | Grupa 3: 17 | + Agnieszka Stasiak 242531 18 | + Maciej Perdaszek 242490 19 | + Igor Bobrukiewicz 242361 20 | + Kamil Włodarczyk 242565 21 | + Krzysztof Kolanek 242425 22 | 23 | Grupa 4: 24 | + Jakub Kalinowski 242413 25 | + Rafał Cybula 242370 26 | + Tomasz Kowalczyk 242432 27 | 28 | Grupa 5: 29 | + Michał Olczak 229972 30 | + Artur Włodarczyk 242564 31 | + Wojciech Stobiński 242538 32 | + Jakub Stępnicki 242537 33 | + Wojciech Żyndul 242575 34 | 35 | Grupa 6: 36 | + Michał Piestrzeniewicz 242493 37 | + Bartłomiej Kałach 242414 38 | + Piotr Kwiatkowski 242447 39 | + Jakub Kozielski 242438 40 | + Marta Glinka 242391 41 | 42 | Grupa 7: 43 | + Aleksander Janicki 242405 44 | + Artur Grzybek 242399 45 | + Michalina Wysocka 230043 46 | + Michał Ferdzyn 242383 47 | 48 | Grupa 8: 49 | + Krzysztof Deka 242377 50 | + Jakub Olejniczak 242484 51 | + Michał Kaźmierski 242421 52 | + Tomasz Zając 242571 53 | 54 | Grupa 9: 55 | + Bartosz Kwieciński 242449 56 | + Kacper Czernik 242371 57 | + Mateusz Grzeszczak 242398 58 | + Adam Rosiak 242511 59 | 60 | Grupa 10 (Dragon Sector): 61 | + Adam Karaszewski 242415 62 | + Marcin Strzelec 242540 63 | + Miłosz Urbaniak 242558 64 | + Wadim Janikowski 242406 65 | 66 | Grupa 11: 67 | + Piotr Płeska 242499 68 | + Adam Przybylski 242506 69 | + Kamil Cieślak 242369 70 | + Maciej Wilczyński 242560 71 | -------------------------------------------------------------------------------- /intro/Git-Maven-GithubActions.md: -------------------------------------------------------------------------------- 1 | # Java - Git - Maven - Github Actions 2 | 3 | **Task 1 - Java & sdkman** 4 | - Install one of the latest Java (JDK 21): [jdk-link](https://www.oracle.com/pl/java/technologies/downloads/) 5 | - Set environment variable: *JAVA_HOME* in your operating system 6 | - Using command line or terminal, type: *java --version* 7 | - ![](https://github.com/zzpj/pl-java2024/blob/main/intro/jdk21-mint.png "jdk21 mint") 8 | - Manage SDK (including JDK) like a pro - using https://sdkman.io/ (Linux/Windows/Mac friendly) 9 | 10 | **Task 2 - Git** 11 | - GitHub account creation: [sign up](https://github.com/) 12 | - Git familiarization: [learn git branching](https://learngitbranching.js.org/) 13 | - [Interesting GIT aliases](https://github.com/jakubnabrdalik/gitkurwa) 14 | 15 | **Task 3 - Maven I (+ Lombok)** 16 | - Familiarize with some theory - [short presentation](https://github.com/zzpj/pl-java2024/blob/main/intro/ZZPJ2021-maven.pdf) 17 | - [Download maven package](https://maven.apache.org/download.cgi?Preferred=http%3A%2F%2Fapache.mirrors.tworzy.net%2F#) 18 | - Set environment variable: `MAVEN_HOME` 19 | - Using command line or terminal, check your maven version: `mvn -v` or `mvn --version` 20 | - Generate project with the archetype „quickstart” (default): `mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4` 21 | - Import project into IDE 22 | - Optional way: [you can create maven project structure using your IDE](https://www.javappa.com/szybki-dostep/maven-pierwsze-kroki) 23 | - Review `pom.xml` 24 | - Build package using Maven (using command line): `mvn clean install` 25 | - Add project's lombok dependency 26 | ``` 27 | 28 | org.projectlombok 29 | lombok 30 | 1.18.30 31 | provided 32 | 33 | ``` 34 | - Create simple Java class with lombok annotation 35 | - Build again using Maven 36 | 37 | **Task 4 - Maven II** 38 | - Create two independent projects 39 | - First provides model-api (use lombok lib) 40 | - Second uses provided api (create model class instances and prints them on console) 41 | - Provide several release versions with updated api 42 | - Localize where model the jars have been deployed 43 | 44 | **Task 5 - GitHub Actions** 45 | - Create a new repository on your GitHub account 46 | - Go to "Actions" tab 47 | - Create "Simple Workflow" that will run on your repository: 48 | - [create simple unit test (so your workflow needs to run tests)](https://octopus.com/blog/githubactions-running-unit-tests) 49 | - [setup "secret" for keeping passwords and use it on your workflow](https://docs.github.com/en/actions/security-guides/encrypted-secrets) 50 | - [add workflow status badge](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/adding-a-workflow-status-badge) 51 | -------------------------------------------------------------------------------- /intro/ZZPJ2021-maven.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzpj/pl-java2024/b3607327e97ffb15868a519cb595df959329c5f8/intro/ZZPJ2021-maven.pdf -------------------------------------------------------------------------------- /intro/jdk21-mint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzpj/pl-java2024/b3607327e97ffb15868a519cb595df959329c5f8/intro/jdk21-mint.png -------------------------------------------------------------------------------- /intro/maven-helpful-snippets.md: -------------------------------------------------------------------------------- 1 | ## Maven helpful snippets 2 | 3 | Generate project structure: 4 | ```sh 5 | mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 6 | ``` 7 | 8 | Use lombok library: 9 | ```xml 10 | 11 | org.projectlombok 12 | lombok 13 | 1.18.6 14 | provided 15 | 16 | ``` 17 | 18 | Add to your pom.xml: 19 | ```xml 20 | 21 | 22 | src/main/resources/config.${env}.properties 23 | 24 | 25 | 26 | 27 | 28 | src/main/resources 29 | true 30 | 31 | *.properties 32 | 33 | 34 | 35 | ``` 36 | 37 | Add to your pom.xml: 38 | ```xml 39 | 40 | 41 | 42 | dev 43 | 44 | true 45 | 46 | 47 | dev 48 | 49 | 50 | 51 | 52 | prod 53 | 54 | prod 55 | 56 | 57 | 58 | ``` 59 | 60 | Read properties: 61 | ```java 62 | public static Properties loadProperties() { 63 | App app = new App(); 64 | Properties prop = app.loadPropertiesFile("config.properties"); 65 | prop.forEach((k, v) -> System.out.println(k + ":" + v)); 66 | return prop; 67 | } 68 | 69 | public Properties loadPropertiesFile(String filePath) { 70 | 71 | Properties prop = new Properties(); 72 | 73 | try (InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream(filePath)) { 74 | prop.load(resourceAsStream); 75 | } catch (IOException e) { 76 | System.err.println("Unable to load properties file : " + filePath); 77 | } 78 | return prop; 79 | } 80 | ``` 81 | -------------------------------------------------------------------------------- /microservices-world/TrainTripEcoSystem/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /microservices-world/TrainTripEcoSystem/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.1 18 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip 19 | -------------------------------------------------------------------------------- /microservices-world/TrainTripEcoSystem/mvnw.cmd: -------------------------------------------------------------------------------- 1 | <# : batch portion 2 | @REM ---------------------------------------------------------------------------- 3 | @REM Licensed to the Apache Software Foundation (ASF) under one 4 | @REM or more contributor license agreements. See the NOTICE file 5 | @REM distributed with this work for additional information 6 | @REM regarding copyright ownership. The ASF licenses this file 7 | @REM to you under the Apache License, Version 2.0 (the 8 | @REM "License"); you may not use this file except in compliance 9 | @REM with the License. You may obtain a copy of the License at 10 | @REM 11 | @REM https://www.apache.org/licenses/LICENSE-2.0 12 | @REM 13 | @REM Unless required by applicable law or agreed to in writing, 14 | @REM software distributed under the License is distributed on an 15 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | @REM KIND, either express or implied. See the License for the 17 | @REM specific language governing permissions and limitations 18 | @REM under the License. 19 | @REM ---------------------------------------------------------------------------- 20 | 21 | @REM ---------------------------------------------------------------------------- 22 | @REM Apache Maven Wrapper startup batch script, version 3.3.1 23 | @REM 24 | @REM Optional ENV vars 25 | @REM MVNW_REPOURL - repo url base for downloading maven distribution 26 | @REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 27 | @REM MVNW_VERBOSE - true: enable verbose log; others: silence the output 28 | @REM ---------------------------------------------------------------------------- 29 | 30 | @IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) 31 | @SET __MVNW_CMD__= 32 | @SET __MVNW_ERROR__= 33 | @SET __MVNW_PSMODULEP_SAVE=%PSModulePath% 34 | @SET PSModulePath= 35 | @FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( 36 | IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) 37 | ) 38 | @SET PSModulePath=%__MVNW_PSMODULEP_SAVE% 39 | @SET __MVNW_PSMODULEP_SAVE= 40 | @SET __MVNW_ARG0_NAME__= 41 | @SET MVNW_USERNAME= 42 | @SET MVNW_PASSWORD= 43 | @IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) 44 | @echo Cannot start maven from wrapper >&2 && exit /b 1 45 | @GOTO :EOF 46 | : end batch / begin powershell #> 47 | 48 | $ErrorActionPreference = "Stop" 49 | if ($env:MVNW_VERBOSE -eq "true") { 50 | $VerbosePreference = "Continue" 51 | } 52 | 53 | # calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties 54 | $distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl 55 | if (!$distributionUrl) { 56 | Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" 57 | } 58 | 59 | switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { 60 | "maven-mvnd-*" { 61 | $USE_MVND = $true 62 | $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" 63 | $MVN_CMD = "mvnd.cmd" 64 | break 65 | } 66 | default { 67 | $USE_MVND = $false 68 | $MVN_CMD = $script -replace '^mvnw','mvn' 69 | break 70 | } 71 | } 72 | 73 | # apply MVNW_REPOURL and calculate MAVEN_HOME 74 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 75 | if ($env:MVNW_REPOURL) { 76 | $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } 77 | $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" 78 | } 79 | $distributionUrlName = $distributionUrl -replace '^.*/','' 80 | $distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' 81 | $MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" 82 | $MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' 83 | $MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" 84 | 85 | if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { 86 | Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" 87 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 88 | exit $? 89 | } 90 | 91 | if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { 92 | Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" 93 | } 94 | 95 | # prepare tmp dir 96 | $TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile 97 | $TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" 98 | $TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null 99 | trap { 100 | if ($TMP_DOWNLOAD_DIR.Exists) { 101 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 102 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 103 | } 104 | } 105 | 106 | New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null 107 | 108 | # Download and Install Apache Maven 109 | Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 110 | Write-Verbose "Downloading from: $distributionUrl" 111 | Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 112 | 113 | $webclient = New-Object System.Net.WebClient 114 | if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { 115 | $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) 116 | } 117 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 118 | $webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null 119 | 120 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 121 | $distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum 122 | if ($distributionSha256Sum) { 123 | if ($USE_MVND) { 124 | Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." 125 | } 126 | Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash 127 | if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { 128 | Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." 129 | } 130 | } 131 | 132 | # unzip and move 133 | Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null 134 | Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null 135 | try { 136 | Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null 137 | } catch { 138 | if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { 139 | Write-Error "fail to move MAVEN_HOME" 140 | } 141 | } finally { 142 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 143 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 144 | } 145 | 146 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 147 | -------------------------------------------------------------------------------- /microservices-world/TrainTripEcoSystem/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.2.6 9 | 10 | 11 | com.zzpj 12 | TrainTripEcoSystem 13 | 0.0.1-SNAPSHOT 14 | TrainTripEcoSystem 15 | Demo project for Spring Boot 16 | 17 | 21 18 | 2023.0.1 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | org.springframework.cloud 27 | spring-cloud-starter-netflix-eureka-server 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-test 33 | test 34 | 35 | 36 | 37 | 38 | 39 | org.springframework.cloud 40 | spring-cloud-dependencies 41 | ${spring-cloud.version} 42 | pom 43 | import 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-maven-plugin 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /microservices-world/TrainTripEcoSystem/src/main/java/com/zzpj/TrainTripEcoSystem/TrainTripEcoSystemApplication.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.TrainTripEcoSystem; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | @EnableEurekaServer 8 | @SpringBootApplication 9 | public class TrainTripEcoSystemApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(TrainTripEcoSystemApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /microservices-world/TrainTripEcoSystem/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=TrainTripEcoSystem 2 | 3 | eureka.client.register-with-eureka=false 4 | eureka.client.fetch-registry=false 5 | 6 | server.port=8761 7 | -------------------------------------------------------------------------------- /microservices-world/TrainTripEcoSystem/src/test/java/com/zzpj/TrainTripEcoSystem/TrainTripEcoSystemApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.TrainTripEcoSystem; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class TrainTripEcoSystemApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /microservices-world/TrainTripManagerService/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /microservices-world/TrainTripManagerService/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.1 18 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip 19 | -------------------------------------------------------------------------------- /microservices-world/TrainTripManagerService/mvnw.cmd: -------------------------------------------------------------------------------- 1 | <# : batch portion 2 | @REM ---------------------------------------------------------------------------- 3 | @REM Licensed to the Apache Software Foundation (ASF) under one 4 | @REM or more contributor license agreements. See the NOTICE file 5 | @REM distributed with this work for additional information 6 | @REM regarding copyright ownership. The ASF licenses this file 7 | @REM to you under the Apache License, Version 2.0 (the 8 | @REM "License"); you may not use this file except in compliance 9 | @REM with the License. You may obtain a copy of the License at 10 | @REM 11 | @REM https://www.apache.org/licenses/LICENSE-2.0 12 | @REM 13 | @REM Unless required by applicable law or agreed to in writing, 14 | @REM software distributed under the License is distributed on an 15 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | @REM KIND, either express or implied. See the License for the 17 | @REM specific language governing permissions and limitations 18 | @REM under the License. 19 | @REM ---------------------------------------------------------------------------- 20 | 21 | @REM ---------------------------------------------------------------------------- 22 | @REM Apache Maven Wrapper startup batch script, version 3.3.1 23 | @REM 24 | @REM Optional ENV vars 25 | @REM MVNW_REPOURL - repo url base for downloading maven distribution 26 | @REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 27 | @REM MVNW_VERBOSE - true: enable verbose log; others: silence the output 28 | @REM ---------------------------------------------------------------------------- 29 | 30 | @IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) 31 | @SET __MVNW_CMD__= 32 | @SET __MVNW_ERROR__= 33 | @SET __MVNW_PSMODULEP_SAVE=%PSModulePath% 34 | @SET PSModulePath= 35 | @FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( 36 | IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) 37 | ) 38 | @SET PSModulePath=%__MVNW_PSMODULEP_SAVE% 39 | @SET __MVNW_PSMODULEP_SAVE= 40 | @SET __MVNW_ARG0_NAME__= 41 | @SET MVNW_USERNAME= 42 | @SET MVNW_PASSWORD= 43 | @IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) 44 | @echo Cannot start maven from wrapper >&2 && exit /b 1 45 | @GOTO :EOF 46 | : end batch / begin powershell #> 47 | 48 | $ErrorActionPreference = "Stop" 49 | if ($env:MVNW_VERBOSE -eq "true") { 50 | $VerbosePreference = "Continue" 51 | } 52 | 53 | # calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties 54 | $distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl 55 | if (!$distributionUrl) { 56 | Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" 57 | } 58 | 59 | switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { 60 | "maven-mvnd-*" { 61 | $USE_MVND = $true 62 | $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" 63 | $MVN_CMD = "mvnd.cmd" 64 | break 65 | } 66 | default { 67 | $USE_MVND = $false 68 | $MVN_CMD = $script -replace '^mvnw','mvn' 69 | break 70 | } 71 | } 72 | 73 | # apply MVNW_REPOURL and calculate MAVEN_HOME 74 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 75 | if ($env:MVNW_REPOURL) { 76 | $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } 77 | $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" 78 | } 79 | $distributionUrlName = $distributionUrl -replace '^.*/','' 80 | $distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' 81 | $MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" 82 | $MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' 83 | $MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" 84 | 85 | if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { 86 | Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" 87 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 88 | exit $? 89 | } 90 | 91 | if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { 92 | Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" 93 | } 94 | 95 | # prepare tmp dir 96 | $TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile 97 | $TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" 98 | $TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null 99 | trap { 100 | if ($TMP_DOWNLOAD_DIR.Exists) { 101 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 102 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 103 | } 104 | } 105 | 106 | New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null 107 | 108 | # Download and Install Apache Maven 109 | Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 110 | Write-Verbose "Downloading from: $distributionUrl" 111 | Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 112 | 113 | $webclient = New-Object System.Net.WebClient 114 | if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { 115 | $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) 116 | } 117 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 118 | $webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null 119 | 120 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 121 | $distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum 122 | if ($distributionSha256Sum) { 123 | if ($USE_MVND) { 124 | Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." 125 | } 126 | Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash 127 | if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { 128 | Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." 129 | } 130 | } 131 | 132 | # unzip and move 133 | Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null 134 | Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null 135 | try { 136 | Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null 137 | } catch { 138 | if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { 139 | Write-Error "fail to move MAVEN_HOME" 140 | } 141 | } finally { 142 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 143 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 144 | } 145 | 146 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 147 | -------------------------------------------------------------------------------- /microservices-world/TrainTripManagerService/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.3.0 9 | 10 | 11 | com.zzpj 12 | TrainTripManagerService 13 | 0.0.1-SNAPSHOT 14 | TrainTripManagerService 15 | Demo project for Spring Boot 16 | 17 | 21 18 | 2023.0.1 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-actuator 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | 31 | org.projectlombok 32 | lombok 33 | true 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-test 38 | test 39 | 40 | 41 | 42 | org.openapitools 43 | jackson-databind-nullable 44 | 0.2.6 45 | 46 | 47 | 48 | org.springdoc 49 | springdoc-openapi-starter-webmvc-ui 50 | 2.5.0 51 | 52 | 53 | 54 | org.springframework.cloud 55 | spring-cloud-starter-netflix-eureka-client 56 | 57 | 58 | 59 | 60 | 61 | 62 | org.springframework.cloud 63 | spring-cloud-dependencies 64 | ${spring-cloud.version} 65 | pom 66 | import 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | org.openapitools 76 | openapi-generator-maven-plugin 77 | 7.6.0 78 | 79 | 80 | 81 | generate 82 | 83 | 84 | ${project.basedir}/api/train-api.yml 85 | spring 86 | com.zzpj.openapi.api 87 | com.zzpj.openapi.model 88 | 89 | true 90 | true 91 | src/gen/java/main 92 | spring-cloud 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | org.springframework.boot 102 | spring-boot-maven-plugin 103 | 104 | 105 | 106 | org.projectlombok 107 | lombok 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /microservices-world/TrainTripManagerService/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=TrainTripManagerService 2 | 3 | server.port=8020 4 | 5 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 6 | eureka.client.fetch-registry=true 7 | eureka.client.register-with-eureka=true -------------------------------------------------------------------------------- /microservices-world/TrainTripManagerService/src/test/java/com/zzpj/TrainTripManagerService/TrainTripManagerServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.TrainTripManagerService; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class TrainTripManagerServiceApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /microservices-world/TrainTripOrganizerService/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /microservices-world/TrainTripOrganizerService/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.1 18 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip 19 | -------------------------------------------------------------------------------- /microservices-world/TrainTripOrganizerService/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.3.0 9 | 10 | 11 | com.zzpj 12 | TrainTripOrganizerService 13 | 0.0.1-SNAPSHOT 14 | TrainTripOrganizerService 15 | Demo project for Spring Boot 16 | 17 | 21 18 | 2023.0.1 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-actuator 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | 31 | org.projectlombok 32 | lombok 33 | true 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-test 38 | test 39 | 40 | 41 | 42 | org.openapitools 43 | jackson-databind-nullable 44 | 0.2.6 45 | 46 | 47 | 48 | org.springdoc 49 | springdoc-openapi-starter-webmvc-ui 50 | 2.5.0 51 | 52 | 53 | 54 | org.springframework.cloud 55 | spring-cloud-starter-netflix-eureka-client 56 | 57 | 58 | 59 | org.springframework.cloud 60 | spring-cloud-starter-loadbalancer 61 | 62 | 63 | 64 | org.springframework.cloud 65 | spring-cloud-starter-config 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | org.springframework.cloud 74 | spring-cloud-dependencies 75 | ${spring-cloud.version} 76 | pom 77 | import 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | org.openapitools 87 | openapi-generator-maven-plugin 88 | 7.6.0 89 | 90 | 91 | 92 | generate 93 | 94 | 95 | ${project.basedir}/api/train-api.yml 96 | java 97 | com.zzpj.openapi.api 98 | com.zzpj.openapi.model 99 | false 100 | false 101 | 102 | true 103 | resttemplate 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | org.springframework.boot 113 | spring-boot-maven-plugin 114 | 115 | 116 | 117 | org.projectlombok 118 | lombok 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /microservices-world/TrainTripOrganizerService/src/main/java/com/zzpj/TrainTripOrganizerService/TrainTripOrganizerServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.TrainTripOrganizerService; 2 | 3 | import com.zzpj.openapi.api.StationsApi; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.boot.CommandLineRunner; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.cloud.client.DefaultServiceInstance; 9 | import org.springframework.cloud.client.ServiceInstance; 10 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 11 | import org.springframework.cloud.client.loadbalancer.LoadBalanced; 12 | import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; 13 | import org.springframework.context.annotation.Bean; 14 | import org.springframework.http.ResponseEntity; 15 | import org.springframework.web.bind.annotation.GetMapping; 16 | import org.springframework.web.bind.annotation.RestController; 17 | import org.springframework.web.client.RestTemplate; 18 | import reactor.core.publisher.Flux; 19 | 20 | import java.util.List; 21 | 22 | @EnableDiscoveryClient 23 | @SpringBootApplication 24 | public class TrainTripOrganizerServiceApplication { 25 | 26 | public static void main(String[] args) { 27 | SpringApplication.run(TrainTripOrganizerServiceApplication.class, args); 28 | } 29 | 30 | @Bean 31 | public StationsApi stationsApi() { 32 | return new StationsApi(); 33 | } 34 | 35 | @Bean 36 | public CommandLineRunner commandLineRunner(StationsApi stationsApi) { 37 | return args -> { 38 | System.out.println(stationsApi.getApiClient().getBasePath()); 39 | stationsApi.getStations().forEach(System.out::println); 40 | }; 41 | } 42 | 43 | @Bean 44 | public ServiceInstanceListSupplier serviceInstanceListSupplier() { 45 | return new TrainTripsManagerSupplier("train-trips-service"); 46 | } 47 | 48 | @Bean 49 | @LoadBalanced 50 | public RestTemplate restTemplate() { 51 | return new RestTemplate(); 52 | } 53 | } 54 | 55 | class TrainTripsManagerSupplier implements ServiceInstanceListSupplier { 56 | 57 | private final String serviceId; 58 | 59 | TrainTripsManagerSupplier(String serviceId) { 60 | this.serviceId = serviceId; 61 | } 62 | 63 | @Override 64 | public String getServiceId() { 65 | return serviceId; 66 | } 67 | 68 | @Override 69 | public Flux> get() { 70 | return Flux.just( 71 | List.of( 72 | new DefaultServiceInstance("001", serviceId, "localhost", 8021, false), 73 | new DefaultServiceInstance("002", serviceId, "localhost", 8022, false), 74 | new DefaultServiceInstance("003", serviceId, "localhost", 8023, false) 75 | ) 76 | ); 77 | } 78 | } 79 | 80 | @RestController 81 | class TrainTripsOrganizerController { 82 | private final RestTemplate restTemplate; 83 | 84 | @Value("${spring.application.name}") 85 | private String applicationName; 86 | 87 | TrainTripsOrganizerController(RestTemplate restTemplate) { 88 | this.restTemplate = restTemplate; 89 | } 90 | 91 | @GetMapping("/info") 92 | public String getHello() { 93 | ResponseEntity forEntity = restTemplate.getForEntity("http://train-trips-service/hello/" + applicationName, String.class); 94 | return forEntity.getBody(); 95 | } 96 | 97 | @Value("${config.server.demo}") 98 | private String message; 99 | 100 | @GetMapping("/getMessage") 101 | public String getMessage() { 102 | return "Property value: " + message; 103 | } 104 | } -------------------------------------------------------------------------------- /microservices-world/TrainTripOrganizerService/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=TrainTripOrganizerService 2 | 3 | server.port=8030 4 | 5 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 6 | eureka.client.fetch-registry=true 7 | eureka.client.register-with-eureka=true 8 | 9 | spring.config.import=optional:configserver: 10 | spring.cloud.config.discovery.enabled=true 11 | spring.cloud.config.discovery.service-id=TrainTripsConfigServer 12 | #spring.cloud.config.name=${spring.application.name} 13 | spring.cloud.config.name=train-trips-organizer-service 14 | spring.cloud.config.profile=dev 15 | spring.cloud.config.label=main 16 | spring.cloud.config.fail-fast=true -------------------------------------------------------------------------------- /microservices-world/TrainTripOrganizerService/src/test/java/com/zzpj/TrainTripOrganizerService/TrainTripOrganizerServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.TrainTripOrganizerService; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class TrainTripOrganizerServiceApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /microservices-world/TrainTripUsersAdapter/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /microservices-world/TrainTripUsersAdapter/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.1 18 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip 19 | -------------------------------------------------------------------------------- /microservices-world/TrainTripUsersAdapter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.3.0 9 | 10 | 11 | com.zzpj 12 | TrainTripUsersAdapter 13 | 0.0.1-SNAPSHOT 14 | TrainTripUsersAdapter 15 | Demo project for Spring Boot 16 | 17 | 21 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-oauth2-client 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-security 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-test 36 | test 37 | 38 | 39 | org.springframework.security 40 | spring-security-test 41 | test 42 | 43 | 44 | 45 | org.keycloak 46 | keycloak-admin-client 47 | 24.0.4 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-maven-plugin 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /microservices-world/TrainTripUsersAdapter/src/main/java/com/zzpj/TrainTripUsersAdapter/TrainTripUsersAdapterApplication.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.TrainTripUsersAdapter; 2 | 3 | import jakarta.servlet.ServletException; 4 | import jakarta.servlet.http.HttpServletRequest; 5 | import jakarta.servlet.http.HttpServletResponse; 6 | import org.keycloak.OAuth2Constants; 7 | import org.keycloak.admin.client.Keycloak; 8 | import org.keycloak.admin.client.KeycloakBuilder; 9 | import org.keycloak.representations.idm.AbstractUserRepresentation; 10 | import org.keycloak.representations.idm.UserRepresentation; 11 | import org.springframework.beans.factory.annotation.Value; 12 | import org.springframework.boot.CommandLineRunner; 13 | import org.springframework.boot.SpringApplication; 14 | import org.springframework.boot.autoconfigure.SpringBootApplication; 15 | import org.springframework.boot.web.client.RestTemplateBuilder; 16 | import org.springframework.context.annotation.Bean; 17 | import org.springframework.http.ResponseEntity; 18 | import org.springframework.security.config.Customizer; 19 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 20 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 21 | import org.springframework.security.core.Authentication; 22 | import org.springframework.security.oauth2.core.oidc.user.OidcUser; 23 | import org.springframework.security.web.SecurityFilterChain; 24 | import org.springframework.security.web.authentication.logout.LogoutHandler; 25 | import org.springframework.stereotype.Component; 26 | import org.springframework.web.bind.annotation.GetMapping; 27 | import org.springframework.web.bind.annotation.RestController; 28 | import org.springframework.web.util.UriComponentsBuilder; 29 | 30 | import java.util.List; 31 | 32 | @SpringBootApplication 33 | public class TrainTripUsersAdapterApplication { 34 | 35 | public static void main(String[] args) { 36 | SpringApplication.run(TrainTripUsersAdapterApplication.class, args); 37 | } 38 | 39 | @Bean 40 | Keycloak keycloak() { 41 | return KeycloakBuilder.builder() 42 | .serverUrl("http://localhost:8999") 43 | .realm("train-trips-ecosystem") 44 | .clientId("admin-cli") 45 | .grantType(OAuth2Constants.PASSWORD) 46 | .username("admin") 47 | .password("admin") 48 | .build(); 49 | } 50 | 51 | @Bean 52 | CommandLineRunner commandLineRunner(Keycloak keycloak) { 53 | return args -> { 54 | 55 | //http://localhost:8999/realms/train-trips-ecosystem 56 | List userRepresentations = keycloak.realm("train-trips-ecosystem") 57 | .users() 58 | .search("user", true); 59 | List usernames = userRepresentations.stream().map(AbstractUserRepresentation::getUsername).toList(); 60 | return; 61 | }; 62 | } 63 | } 64 | 65 | @EnableWebSecurity 66 | class SecurityConfig { 67 | 68 | @Bean 69 | KeycloakLogoutHandler keycloakLogoutHandler() { 70 | return new KeycloakLogoutHandler(); 71 | } 72 | 73 | @Bean 74 | public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { 75 | 76 | http.authorizeHttpRequests(auth 77 | -> auth.requestMatchers("/external") 78 | .permitAll() 79 | .anyRequest() 80 | .authenticated() 81 | ); 82 | http.oauth2Login(Customizer.withDefaults()); 83 | http.logout(logout -> logout.addLogoutHandler(keycloakLogoutHandler()).logoutUrl("/external")); 84 | return http.build(); 85 | } 86 | } 87 | 88 | @RestController 89 | class UserController { 90 | 91 | @GetMapping("/internal") 92 | public String getSecretInfo() { 93 | return "secret info, visible after login..."; 94 | } 95 | 96 | @GetMapping("/external") 97 | public String getExternalInfo() { 98 | return "content visible for all, no login required..."; 99 | } 100 | 101 | @GetMapping("/logout") 102 | public String logout(HttpServletRequest request) throws ServletException { 103 | request.logout(); 104 | return "redirect:/"; 105 | } 106 | 107 | @Value("${spring.security.oauth2.client.provider.keycloak.issuer-uri}") 108 | private String issuerUrl; 109 | 110 | @GetMapping("/profile") 111 | public void profile(HttpServletResponse response) { 112 | response.setHeader("Location", issuerUrl + "/account"); 113 | response.setStatus(302); 114 | } 115 | } 116 | 117 | @Component 118 | class KeycloakLogoutHandler implements LogoutHandler { 119 | 120 | @Value("${spring.security.oauth2.client.provider.keycloak.issuer-uri}") 121 | private String issuerUrl; 122 | 123 | @Override 124 | public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { 125 | 126 | String logout = issuerUrl + "/protocol/openid-connect/logout"; 127 | 128 | UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder 129 | .fromUriString(logout) 130 | .queryParam("id_token_hint", ((OidcUser) authentication.getPrincipal()).getIdToken().getTokenValue()); 131 | 132 | ResponseEntity logoutEntity = new RestTemplateBuilder() 133 | .build() 134 | .getForEntity(uriComponentsBuilder.toUriString(), String.class); 135 | 136 | if (!logoutEntity.getStatusCode().is2xxSuccessful()) { 137 | throw new RuntimeException("Logout failed: " + logoutEntity.getBody()); 138 | } 139 | } 140 | } -------------------------------------------------------------------------------- /microservices-world/TrainTripUsersAdapter/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=TrainTripUsersAdapter 2 | 3 | server.port=8090 4 | 5 | spring.security.oauth2.client.registration.keycloak.client-id=train-trips-users-adapter 6 | spring.security.oauth2.client.registration.keycloak.client-secret=4gj9GNobdbGmLiayjftJwLN7TID1Qm5A 7 | spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code 8 | spring.security.oauth2.client.registration.keycloak.scope=openid 9 | 10 | spring.security.oauth2.client.provider.keycloak.issuer-uri=http://localhost:8999/realms/train-trips-ecosystem -------------------------------------------------------------------------------- /microservices-world/TrainTripUsersAdapter/src/test/java/com/zzpj/TrainTripUsersAdapter/TrainTripUsersAdapterApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.TrainTripUsersAdapter; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class TrainTripUsersAdapterApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /microservices-world/TrainTripsConfigServer/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /microservices-world/TrainTripsConfigServer/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.1 18 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip 19 | -------------------------------------------------------------------------------- /microservices-world/TrainTripsConfigServer/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.2.6 9 | 10 | 11 | com.zzpj 12 | TrainTripsConfigServer 13 | 0.0.1-SNAPSHOT 14 | TrainTripsConfigServer 15 | Demo project for Spring Boot 16 | 17 | 21 18 | 2023.0.1 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | org.springframework.cloud 27 | spring-cloud-config-server 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-netflix-eureka-client 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-test 37 | test 38 | 39 | 40 | 41 | 42 | 43 | org.springframework.cloud 44 | spring-cloud-dependencies 45 | ${spring-cloud.version} 46 | pom 47 | import 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-maven-plugin 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /microservices-world/TrainTripsConfigServer/src/main/java/com/zzpj/TrainTripsConfigServer/TrainTripsConfigServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.TrainTripsConfigServer; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.config.server.EnableConfigServer; 7 | 8 | @SpringBootApplication 9 | @EnableDiscoveryClient 10 | @EnableConfigServer 11 | public class TrainTripsConfigServerApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(TrainTripsConfigServerApplication.class, args); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /microservices-world/TrainTripsConfigServer/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=TrainTripsConfigServer 2 | 3 | server.port=8040 4 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 5 | 6 | 7 | spring.cloud.config.server.git.uri=https://github.com/zzpj/demo-config-server.git 8 | spring.cloud.config.server.git.default-label=main 9 | spring.cloud.config.server.git.clone-on-start=true -------------------------------------------------------------------------------- /microservices-world/TrainTripsConfigServer/src/test/java/com/zzpj/TrainTripsConfigServer/TrainTripsConfigServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.TrainTripsConfigServer; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class TrainTripsConfigServerApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-security/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /spring-security/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.2.5 9 | 10 | 11 | com.example 12 | demo 13 | 0.0.1-SNAPSHOT 14 | security-demo 15 | Demo project for Spring Security 16 | 17 | 17 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | 24 | 25 | 26 | org.projectlombok 27 | lombok 28 | true 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-security 33 | 3.2.5 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-oauth2-resource-server 38 | 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-test 44 | test 45 | 46 | 47 | 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-maven-plugin 53 | 54 | 55 | 56 | org.projectlombok 57 | lombok 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /spring-security/src/main/java/com/example/demo/SecurityDemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SecurityDemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SecurityDemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-security/src/main/java/com/example/demo/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.config; 2 | 3 | import com.nimbusds.jose.jwk.JWK; 4 | import com.nimbusds.jose.jwk.JWKSet; 5 | import com.nimbusds.jose.jwk.RSAKey; 6 | import com.nimbusds.jose.jwk.source.ImmutableJWKSet; 7 | import com.nimbusds.jose.jwk.source.JWKSource; 8 | import com.nimbusds.jose.proc.SecurityContext; 9 | import org.springframework.beans.factory.annotation.Value; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.security.config.Customizer; 13 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 14 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 15 | import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer; 16 | import org.springframework.security.config.http.SessionCreationPolicy; 17 | import org.springframework.security.core.userdetails.User; 18 | import org.springframework.security.core.userdetails.UserDetails; 19 | import org.springframework.security.core.userdetails.UserDetailsService; 20 | import org.springframework.security.crypto.factory.PasswordEncoderFactories; 21 | import org.springframework.security.crypto.password.PasswordEncoder; 22 | import org.springframework.security.oauth2.jwt.JwtDecoder; 23 | import org.springframework.security.oauth2.jwt.JwtEncoder; 24 | import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; 25 | import org.springframework.security.oauth2.jwt.NimbusJwtEncoder; 26 | import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint; 27 | import org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler; 28 | import org.springframework.security.provisioning.InMemoryUserDetailsManager; 29 | import org.springframework.security.web.SecurityFilterChain; 30 | 31 | import java.security.interfaces.RSAPrivateKey; 32 | import java.security.interfaces.RSAPublicKey; 33 | 34 | @Configuration 35 | @EnableWebSecurity 36 | public class SecurityConfig { 37 | @Value("${jwk.public.key}") 38 | private RSAPublicKey rsaPublicKey; 39 | 40 | @Value("${jwk.private.key}") 41 | private RSAPrivateKey rsaPrivateKey; 42 | 43 | @Bean 44 | public JwtEncoder jwtEncoder() { 45 | JWK jwk = new RSAKey.Builder(rsaPublicKey).privateKey(rsaPrivateKey).build(); 46 | JWKSource jwkSource = new ImmutableJWKSet<>(new JWKSet(jwk)); 47 | return new NimbusJwtEncoder(jwkSource); // set up encoder with certificate keys 48 | } 49 | 50 | @Bean 51 | public JwtDecoder jwtDecoder() { 52 | return NimbusJwtDecoder.withPublicKey(rsaPublicKey).build(); // set up decoder with certificate public key 53 | } 54 | 55 | @Bean 56 | public PasswordEncoder passwordEncoder() { 57 | return PasswordEncoderFactories.createDelegatingPasswordEncoder(); // provide password encoder 58 | } 59 | 60 | @Bean 61 | public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) { 62 | UserDetails userAdmin = User.withUsername("admin") 63 | .password(passwordEncoder.encode("admin")) 64 | .roles("ADMIN") 65 | .build(); // create mock user 66 | return new InMemoryUserDetailsManager(userAdmin); // add mock user(s) to manager 67 | } 68 | 69 | @Bean 70 | public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { 71 | http 72 | .csrf(CsrfConfigurer::disable) // disable csrf when testing via postman/insomnia, otherwise we will not be able to send requests 73 | .authorizeHttpRequests(request -> request 74 | .requestMatchers("/get-token").permitAll() 75 | .anyRequest().hasAuthority("SCOPE_ROLE_ADMIN") 76 | ) // authorize http requests: the /get-token endpoint is available for everyone, any other one - for admin only (role prefix matters) 77 | .httpBasic(Customizer.withDefaults()) // enable basic authentication for endpoints with Authorization header 78 | .oauth2ResourceServer(oauth2 -> oauth2.jwt(jwtConfigurer -> jwtConfigurer.decoder(jwtDecoder()))) // use JWT tokens as an authentication mechanism 79 | .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // create stateless sessions 80 | .exceptionHandling(e -> e 81 | .authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint()) 82 | .accessDeniedHandler(new BearerTokenAccessDeniedHandler()) 83 | ); // exception handling 84 | 85 | return http.build(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /spring-security/src/main/java/com/example/demo/controller/TokenProviderController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.controller; 2 | 3 | import com.nimbusds.jwt.JWTClaimsSet; 4 | import org.springframework.security.core.GrantedAuthority; 5 | import org.springframework.security.oauth2.jwt.JwtClaimsSet; 6 | import lombok.RequiredArgsConstructor; 7 | import org.springframework.security.core.Authentication; 8 | import org.springframework.security.oauth2.jwt.JwtEncoder; 9 | import org.springframework.security.oauth2.jwt.JwtEncoderParameters; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | import java.time.Instant; 15 | import java.util.stream.Collectors; 16 | 17 | @RestController 18 | @RequiredArgsConstructor 19 | @RequestMapping("/get-token") 20 | public class TokenProviderController { 21 | private final JwtEncoder jwtEncoder; 22 | 23 | @PostMapping 24 | public String generateToken(Authentication auth) { 25 | Instant issuedAt = Instant.now(); 26 | Instant expiresAt = issuedAt.plusSeconds(120); 27 | 28 | String scope = auth.getAuthorities() 29 | .stream() 30 | .map(GrantedAuthority::getAuthority) 31 | .collect(Collectors.joining(" ")); // get user authorities from the authentication header and join them 32 | 33 | JwtClaimsSet claims = JwtClaimsSet.builder() 34 | .issuer("me") 35 | .issuedAt(issuedAt) 36 | .expiresAt(expiresAt) 37 | .subject(auth.getName()) // add the user a token should be issued to 38 | .claim("scope", scope) // add user roles 39 | .build(); 40 | 41 | return jwtEncoder.encode(JwtEncoderParameters.from(claims)).getTokenValue(); // generate token based on provided data 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /spring-security/src/main/java/com/example/demo/controller/UsersController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.controller; 2 | 3 | import com.example.demo.model.dao.UserDao; 4 | import com.example.demo.service.UsersService; 5 | import lombok.RequiredArgsConstructor; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | import java.util.List; 10 | 11 | @RestController 12 | @RequiredArgsConstructor() 13 | @RequestMapping("/users") 14 | public class UsersController { 15 | private final UsersService usersService; 16 | 17 | @GetMapping() 18 | public ResponseEntity> getUsers() { 19 | return ResponseEntity.ok(usersService.getUsers()); 20 | } 21 | 22 | @GetMapping("/{id}") 23 | public ResponseEntity getUser(@PathVariable Long id) { 24 | UserDao userDao = usersService.findUserById(id); 25 | if (userDao != null) { 26 | return ResponseEntity.ok(userDao); 27 | } else { 28 | return ResponseEntity.notFound().build(); 29 | } 30 | } 31 | 32 | @PostMapping("/add-user") 33 | public ResponseEntity createUser(@RequestBody UserDao userDao) { 34 | UserDao newUser = usersService.addUser(userDao); 35 | if (newUser != null) { 36 | return ResponseEntity.ok(userDao); 37 | } else { 38 | return ResponseEntity.badRequest().build(); 39 | } 40 | } 41 | 42 | @DeleteMapping("/delete-user/{id}") 43 | public ResponseEntity deleteUser(@PathVariable Long id) { 44 | UserDao deletedUser = usersService.deleteUser(id); 45 | return ResponseEntity.ok(deletedUser); 46 | } 47 | 48 | @PutMapping("/update-user/{id}") 49 | public ResponseEntity updateUser(@PathVariable Long id, @RequestBody UserDao userDao) { 50 | UserDao updatedUser = usersService.updateUser(userDao); 51 | if (updatedUser != null) { 52 | return ResponseEntity.ok(userDao); 53 | } else { 54 | return ResponseEntity.notFound().build(); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /spring-security/src/main/java/com/example/demo/model/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model.dao; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @NoArgsConstructor 8 | @AllArgsConstructor 9 | @Data 10 | public class UserDao { 11 | private Long id; 12 | private String username; 13 | private String password; 14 | private String email; 15 | private String phone; 16 | private String address; 17 | private String zipCode; 18 | } 19 | -------------------------------------------------------------------------------- /spring-security/src/main/java/com/example/demo/model/dto/UserDto.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.model.dto; 2 | 3 | public class UserDto { 4 | // not implemented. As you can see in the dao package, 5 | // UserDao class has some fields which should not be passed to a client e.g. password or address. 6 | // Before UserDao is sent to the client, it has to be mapped to UserDto (Data Access Object -> Data Transfer Object) 7 | // When dao is mapped to dto, such data as passwords are ignored. 8 | // The topic is not related to Spring Security itself, but is important when creating secure systems 9 | } 10 | -------------------------------------------------------------------------------- /spring-security/src/main/java/com/example/demo/service/UsersService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | import com.example.demo.model.dao.UserDao; 4 | import org.springframework.stereotype.Service; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | @Service 10 | public class UsersService { 11 | private List users; 12 | 13 | { 14 | users = new ArrayList<>() {{ 15 | add(new UserDao(1L, "user_1", "pwd_1", "email_1@example.com", "999_000_000", "address_1", "99-999")); 16 | add(new UserDao(2L, "user_2", "pwd_2", "email_2@example.com", "999_000_000", "address_2", "99-999")); 17 | add(new UserDao(3L, "user_3", "pwd_3", "email_3@example.com", "999_000_000", "address_3", "99-999")); 18 | add(new UserDao(4L, "user_4", "pwd_4", "email_4@example.com", "999_000_000", "address_4", "99-999")); 19 | add(new UserDao(5L, "user_5", "pwd_5", "email_5@example.com", "999_000_000", "address_5", "99-999")); 20 | }}; 21 | } 22 | 23 | public List getUsers() { 24 | return users; 25 | } 26 | 27 | public UserDao addUser(UserDao userDao) { 28 | UserDao existingUser = findUserById(userDao.getId()); 29 | if (existingUser == null) { 30 | users.add(userDao); 31 | return userDao; 32 | } else { 33 | return null; 34 | } 35 | } 36 | 37 | public UserDao deleteUser(Long id) { 38 | UserDao existingUser = findUserById(id); 39 | users.remove(existingUser); 40 | return existingUser; 41 | } 42 | 43 | public UserDao findUserById(Long id) { 44 | return users 45 | .stream() 46 | .filter(user -> user.getId().equals(id)) 47 | .findAny() 48 | .orElse(null); 49 | } 50 | 51 | public UserDao updateUser(UserDao userDao) { 52 | UserDao existingUser = findUserById(userDao.getId()); 53 | if (existingUser != null) { 54 | users.remove(existingUser); 55 | users.add(userDao); 56 | return userDao; 57 | } else { 58 | return null; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /spring-security/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=security-demo 2 | 3 | jwk.private.key=classpath:cert/cert.key 4 | jwk.public.key=classpath:cert/cert.pub -------------------------------------------------------------------------------- /spring-security/src/main/resources/cert/cert.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDGi5Lwlgl5J581 3 | /lCtzbB9A5cV241arGMKk11ZWfgjXGOa8l1ivio1gqP2mHCYdSusEf4GP+oI3Rz7 4 | z3ldsM2LXhK5xPQQscdejH5xlJvaOenWeAK410DSxmVx31KjXo/DQQaFZL71NWxF 5 | 9VHEPsfL/caXq+7S8A1EAJVozM2l6wvRS5UvDgdPQTyFfocf+IVFjeMGdwgJWG/a 6 | ojBCGbOafdixUNStOIVj5NyQ2/FSUJWZHPXKens4TRP1xBhfnLpixFckV/PaXIMb 7 | otkRtDIsjtm1nLz7uUuz/uRe66mlExCU4L+pMoXOLDRjRxAVhEok9ONaC1PLje7g 8 | eakvgO/NAgMBAAECggEBAIzq9ZDivLiMAbl91l91lSU1zh9KZCqOHgGclG3dqHvY 9 | kC2ihduWozi1j5Bvo8LhruyDHKvs4zwFTBQBrt9rpIedbmcBvkS3GY0m5HvTAUdD 10 | QY/iP/RXev/eppPK8MlZTWpFFc7JsasyjrWcp7tE3+QOK8zs0CZREOlKDMGEUxXF 11 | 3LjiCnt5YcBEnPA1VOoh2lBWa4IFHWfAKr/AYlskh6Jy3HpFcir//+4Jlm2NBf2Y 12 | 6fkoP2i03AUT8Rn5KUDHjnbd/KzxEDJ9QM9/B4KslmXPYIVTfx5Y7QHj0yMDVN00 13 | QZKVczsL74oWEkaw6SbJGzMq8S8T5/NHwoxTa6+6geECgYEA6RVACsSENvZYkCWC 14 | Yq+l28WMEb02EftrH4umic9BZuzcrSPg1z/nLxe8O2R5b1HauUM/ZPULNJr3jSnR 15 | h8n9oouLc0qQ/uRZp9k1kjDuU/XL4b/LKh2LSSmaZsGzZ0ryaD5MQQPFVJyh0/aV 16 | srGXX1CHTDLhjzQwh9w1b3XV9IUCgYEA2hD//fvDOecdSsk7+8JT7OxwxV5Rb8Rs 17 | WygVM+vZBCbjPywOomO2iD4SeDLEOKV5svV9n7XQpDyXjWEjP5aaJkkLk262KLxe 18 | lVZthkUnDkN/h/l+tYOQDJMd3kqR0ekZdchzDkxnpZVjldU0hwmqPFpmxmmMDnyy 19 | LOG0PX6RtKkCgYEAxZidRUOaLpojNHiIE6+CtVDA0R0N5Kq3AvQ6CCRq9p2g6ys6 20 | ZmCnVZYSnmssQ4IqIdrvuF/A0yT47nRgTHSiEBWq799sEpp1o0USFFBlC0qaQFR/ 21 | IMIRHcImQiy+MbgoztTZglh3BqcOzgoCmI3TnRtAyAlujR+acOLvbgGAk50CgYAg 22 | /ol9KGa1kB6CfkgxI4oHQw8dDdRMkO/EKyBqJrlDQ48Gs+fS8jtgCeRJg4Tk/USY 23 | q0RCsgPLlc9oeNYYfPT97fdua0Xsi/PTrKwNsNDj+5qEPF/LnwhgnrHaPHYryJUt 24 | mRKviyfzidLzjLrR48h6MUNzqeyjFILw/4WB+HCbYQKBgFcV52W1JWOW2NGQEyMC 25 | Ryl4IdnOymACDalFFKDEI5gqelxWnXb8wssm1fnL+oGi9ZrZOKN91Im0jMwqHesU 26 | yCLHLp8oZyWMfkXbh5Q9+yl54/mPnK9euVhD/FRSQyWXgdmdApgSkD9fvuZxnf3z 27 | 2Fb74qCpbsZ1iyse01ryLyTR 28 | -----END PRIVATE KEY----- -------------------------------------------------------------------------------- /spring-security/src/main/resources/cert/cert.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxouS8JYJeSefNf5Qrc2w 3 | fQOXFduNWqxjCpNdWVn4I1xjmvJdYr4qNYKj9phwmHUrrBH+Bj/qCN0c+895XbDN 4 | i14SucT0ELHHXox+cZSb2jnp1ngCuNdA0sZlcd9So16Pw0EGhWS+9TVsRfVRxD7H 5 | y/3Gl6vu0vANRACVaMzNpesL0UuVLw4HT0E8hX6HH/iFRY3jBncICVhv2qIwQhmz 6 | mn3YsVDUrTiFY+TckNvxUlCVmRz1ynp7OE0T9cQYX5y6YsRXJFfz2lyDG6LZEbQy 7 | LI7ZtZy8+7lLs/7kXuuppRMQlOC/qTKFziw0Y0cQFYRKJPTjWgtTy43u4HmpL4Dv 8 | zQIDAQAB 9 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /spring-security/src/test/java/com/example/demo/SecurityDemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SecurityDemoApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /spring/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzpj/pl-java2024/b3607327e97ffb15868a519cb595df959329c5f8/spring/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /spring/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar 3 | -------------------------------------------------------------------------------- /spring/ZZPJ2024-springboot.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzpj/pl-java2024/b3607327e97ffb15868a519cb595df959329c5f8/spring/ZZPJ2024-springboot.pdf -------------------------------------------------------------------------------- /spring/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.2.4 9 | 10 | 11 | com.zzpj 12 | EventManager 13 | 0.0.1-SNAPSHOT 14 | EventManager 15 | EventManager 16 | 17 | 21 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-actuator 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-data-jpa 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | com.h2database 35 | h2 36 | runtime 37 | 38 | 39 | org.projectlombok 40 | lombok 41 | true 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-starter-test 46 | test 47 | 48 | 49 | org.springdoc 50 | springdoc-openapi-starter-webmvc-ui 51 | 2.5.0 52 | 53 | 54 | org.hibernate 55 | hibernate-validator 56 | 8.0.1.Final 57 | 58 | 59 | 60 | 61 | 62 | 63 | org.springframework.boot 64 | spring-boot-maven-plugin 65 | 66 | 67 | 68 | org.projectlombok 69 | lombok 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /spring/src/main/java/com/zzpj/EventManager/EventConfig.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.EventManager; 2 | 3 | import com.zzpj.EventManager.model.Event; 4 | import com.zzpj.EventManager.service.EventService; 5 | import io.swagger.v3.oas.models.OpenAPI; 6 | import io.swagger.v3.oas.models.info.Contact; 7 | import io.swagger.v3.oas.models.info.Info; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.context.annotation.Profile; 12 | 13 | import java.time.LocalDateTime; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | @Configuration 18 | public class EventConfig { 19 | 20 | // @Bean 21 | // public EventService eventService() { 22 | // List eventList = new ArrayList<>(); 23 | // eventList.add(new Event(1L, "event-name", "desc", 120.0d, 24 | // LocalDateTime.of(2023, 12, 12, 20, 00))); 25 | // eventList.add(new Event(2L, "second-event-name", "desc", 100.0d, 26 | // LocalDateTime.of(2023, 12, 24, 10, 00))); 27 | // return new EventService(eventList); 28 | // } 29 | 30 | @Value("${info.app.name}") 31 | private String appName; 32 | @Value("${info.app.description}") 33 | private String appDescription; 34 | @Value("${info.app.version}") 35 | private String appVersion; 36 | 37 | 38 | @Bean 39 | @Profile("prod") 40 | public OpenAPI openAPI() { 41 | 42 | Contact contact = new Contact(); 43 | contact.name("Zbyszko on PROD"); 44 | contact.email("your@email.com"); 45 | 46 | Info info = new Info(); 47 | info.setTitle(appName); 48 | info.setDescription(appDescription); 49 | info.setVersion(appVersion); 50 | info.setContact(contact); 51 | 52 | OpenAPI openAPI = new OpenAPI(); 53 | openAPI.setInfo(info); 54 | return openAPI; 55 | } 56 | 57 | 58 | @Bean 59 | @Profile("!prod") 60 | public OpenAPI devOpenAPI() { 61 | 62 | Contact contact = new Contact(); 63 | contact.name("Zbyszko not on PRoD"); 64 | contact.email("your@email.com"); 65 | 66 | Info info = new Info(); 67 | info.setTitle(appName); 68 | info.setDescription(appDescription); 69 | info.setVersion(appVersion); 70 | info.setContact(contact); 71 | 72 | OpenAPI openAPI = new OpenAPI(); 73 | openAPI.setInfo(info); 74 | return openAPI; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /spring/src/main/java/com/zzpj/EventManager/EventExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.EventManager; 2 | 3 | import com.zzpj.EventManager.model.EventErrorResponse; 4 | import org.springframework.context.support.DefaultMessageSourceResolvable; 5 | import org.springframework.http.HttpHeaders; 6 | import org.springframework.http.HttpStatusCode; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.MethodArgumentNotValidException; 9 | import org.springframework.web.bind.annotation.ControllerAdvice; 10 | import org.springframework.web.context.request.WebRequest; 11 | import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; 12 | 13 | import java.time.LocalDateTime; 14 | 15 | @ControllerAdvice 16 | public class EventExceptionHandler extends ResponseEntityExceptionHandler { 17 | 18 | @Override 19 | protected ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { 20 | EventErrorResponse eventErrorResponse = new EventErrorResponse(); 21 | eventErrorResponse.setLocalDateTime(LocalDateTime.now()); 22 | eventErrorResponse.setStatus(status.value()); 23 | 24 | eventErrorResponse.setErrors(ex.getBindingResult() 25 | .getFieldErrors() 26 | .stream() 27 | .map(DefaultMessageSourceResolvable::getDefaultMessage) 28 | .toList()); 29 | 30 | return new ResponseEntity<>(eventErrorResponse, headers, status); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spring/src/main/java/com/zzpj/EventManager/EventManagerApplication.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.EventManager; 2 | 3 | import io.swagger.v3.oas.annotations.Operation; 4 | import io.swagger.v3.oas.annotations.media.Content; 5 | import io.swagger.v3.oas.annotations.media.Schema; 6 | import io.swagger.v3.oas.annotations.responses.ApiResponse; 7 | import io.swagger.v3.oas.annotations.responses.ApiResponses; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.boot.SpringApplication; 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.bind.annotation.PathVariable; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | @SpringBootApplication 16 | public class EventManagerApplication { 17 | public static void main(String[] args) { 18 | SpringApplication.run(EventManagerApplication.class, args); 19 | } 20 | } 21 | 22 | @RestController 23 | class TestController { 24 | 25 | @Value("${spring.application.name}") 26 | private String applicationName; 27 | 28 | 29 | @Operation( 30 | summary = "Get Service Name and say hello to user", 31 | description = "Get Service Name and say hello to user") 32 | @ApiResponses({ 33 | @ApiResponse(responseCode = "200", content = { @Content(schema = @Schema(implementation = String.class), mediaType = "application/json") }), 34 | @ApiResponse(responseCode = "404", description = "Not found"), 35 | @ApiResponse(responseCode = "500", description = "Internal Server Error") }) 36 | @GetMapping("/hello/{name}") 37 | public String getHelloMessage(@PathVariable String name) { 38 | return "Hello World" + name + " from app " + applicationName; 39 | } 40 | } -------------------------------------------------------------------------------- /spring/src/main/java/com/zzpj/EventManager/controller/EventController.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.EventManager.controller; 2 | 3 | 4 | import com.zzpj.EventManager.model.Event; 5 | import com.zzpj.EventManager.model.EventErrorResponse; 6 | import com.zzpj.EventManager.service.EventService; 7 | import io.swagger.v3.oas.annotations.Operation; 8 | import io.swagger.v3.oas.annotations.media.Content; 9 | import io.swagger.v3.oas.annotations.media.Schema; 10 | import io.swagger.v3.oas.annotations.responses.ApiResponse; 11 | import io.swagger.v3.oas.annotations.responses.ApiResponses; 12 | import jakarta.validation.Valid; 13 | import lombok.AllArgsConstructor; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.web.bind.annotation.*; 16 | 17 | import java.util.List; 18 | 19 | @RestController 20 | @AllArgsConstructor 21 | public class EventController { 22 | 23 | private final EventService eventService; 24 | 25 | @GetMapping("/getAllEvents") 26 | public List getAllEvents(){ 27 | return eventService.getAllEvents(); 28 | } 29 | 30 | @GetMapping("/getEvent/{id}") 31 | public Event getEvent(@PathVariable("id") Long id) { 32 | return eventService.getEvent(id); 33 | } 34 | 35 | 36 | @Operation( 37 | summary = "Adds event", 38 | description = "Adds event to event list") 39 | @ApiResponses({ 40 | @ApiResponse(responseCode = "200", content = { @Content(schema = @Schema(implementation = String.class), mediaType = "application/json") }), 41 | @ApiResponse(responseCode = "400", content = { @Content(schema = @Schema(implementation = EventErrorResponse.class), mediaType = "application/json") }), 42 | @ApiResponse(responseCode = "500", description = "Internal Server Error") }) 43 | @PostMapping("/addEvent") 44 | public void addEvent(@Valid @RequestBody Event event) { 45 | eventService.addEvent(event); 46 | } 47 | 48 | @DeleteMapping("/delete/{id}") 49 | public void removeEvent(@PathVariable("id") Long id) { 50 | eventService.deleteEvent(id); 51 | } 52 | 53 | @PutMapping("update/{id}") 54 | public Event updateEvent(@PathVariable Long id, @RequestBody Event event) { 55 | return eventService.updateEvent(event); 56 | } 57 | 58 | @GetMapping("/getAllFreeEvents") 59 | public List getAllFreeEvents(){ 60 | return eventService.getAllFreeEvents(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /spring/src/main/java/com/zzpj/EventManager/model/Event.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.EventManager.model; 2 | 3 | import jakarta.persistence.Entity; 4 | import jakarta.persistence.GeneratedValue; 5 | import jakarta.persistence.GenerationType; 6 | import jakarta.persistence.Id; 7 | import jakarta.validation.constraints.NotNull; 8 | import jakarta.validation.constraints.Positive; 9 | import jakarta.validation.constraints.Size; 10 | import jakarta.validation.constraints.NotBlank; 11 | import lombok.AllArgsConstructor; 12 | import lombok.Data; 13 | import lombok.NoArgsConstructor; 14 | 15 | import java.time.LocalDateTime; 16 | 17 | @Data 18 | @AllArgsConstructor 19 | @Entity 20 | @NoArgsConstructor 21 | 22 | public class Event { 23 | 24 | @Id 25 | @GeneratedValue(strategy = GenerationType.IDENTITY) 26 | private Long id; 27 | 28 | @Size(min = 4, max = 50) 29 | private String name; 30 | 31 | @NotBlank(message = "description cannot be empty") 32 | private String description; 33 | 34 | @Positive(message = "please remember about minimal price") 35 | private Double entranceFee; 36 | 37 | @NotNull 38 | private LocalDateTime startDate; 39 | } 40 | -------------------------------------------------------------------------------- /spring/src/main/java/com/zzpj/EventManager/model/EventErrorResponse.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.EventManager.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.time.LocalDateTime; 6 | import java.util.List; 7 | 8 | @Data 9 | public class EventErrorResponse { 10 | 11 | LocalDateTime localDateTime; 12 | Integer status; 13 | List errors; 14 | } 15 | -------------------------------------------------------------------------------- /spring/src/main/java/com/zzpj/EventManager/repository/EventRepository.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.EventManager.repository; 2 | 3 | import com.zzpj.EventManager.model.Event; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.data.jpa.repository.Query; 6 | import org.springframework.data.repository.query.Param; 7 | 8 | import java.util.List; 9 | 10 | public interface EventRepository extends JpaRepository { 11 | 12 | @Query("SELECT e FROM Event e WHERE e.entranceFee = :goodPrice") 13 | List findAllFreeEvents(@Param("goodPrice") Double goodPrice); 14 | } 15 | -------------------------------------------------------------------------------- /spring/src/main/java/com/zzpj/EventManager/service/EventService.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.EventManager.service; 2 | 3 | import com.zzpj.EventManager.model.Event; 4 | import com.zzpj.EventManager.repository.EventRepository; 5 | import lombok.AllArgsConstructor; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.List; 9 | 10 | @Service 11 | @AllArgsConstructor 12 | public class EventService { 13 | 14 | private final EventRepository eventRepository; 15 | 16 | public List getAllEvents() { 17 | return eventRepository.findAll(); 18 | } 19 | 20 | public void addEvent(Event event) { 21 | eventRepository.save(event); 22 | } 23 | 24 | public void deleteEvent(Long id) { 25 | eventRepository.deleteById(id.intValue()); 26 | } 27 | 28 | public Event getEvent(Long id) { 29 | return eventRepository.findById(id.intValue()).orElse(null); 30 | } 31 | 32 | public Event updateEvent(Event event) { 33 | return eventRepository.save(event); 34 | } 35 | 36 | public List getAllFreeEvents() { 37 | return eventRepository.findAllFreeEvents(0.0); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /spring/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=EventManager 2 | 3 | management.endpoints.web.exposure.include=* 4 | management.info.env.enabled=true 5 | 6 | info.app.name=${spring.application.name} 7 | info.app.description=This is event manager service 8 | info.app.version=0.0.1-alpha 9 | 10 | #server.port=8020 11 | 12 | 13 | #--- 14 | spring.config.activate.on-profile=dev 15 | info.app.description=This is event manager service on DEV 16 | server.port=8021 17 | #--- 18 | spring.config.activate.on-profile=int 19 | info.app.description=This is event manager service on INT 20 | server.port=8022 21 | #--- 22 | spring.config.activate.on-profile=prod 23 | info.app.description=This is event manager service on PROD 24 | server.port=8023 -------------------------------------------------------------------------------- /spring/src/test/java/com/zzpj/EventManager/EventManagerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.zzpj.EventManager; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class EventManagerApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | --------------------------------------------------------------------------------