├── .gitignore ├── README.md ├── intellij-tips.iml ├── pom.xml └── src ├── main ├── java │ └── victor │ │ └── training │ │ └── intellij │ │ ├── refactoring │ │ ├── BooleanLogic.java │ │ ├── ExtractMethod.java │ │ ├── Fields.java │ │ ├── LocalVariables.java │ │ ├── Parameters.java │ │ ├── extract_delegate │ │ │ ├── LargeEntity.java │ │ │ └── LargeService.java │ │ └── extract_interface │ │ │ ├── Service1.java │ │ │ ├── Service2.java │ │ │ └── TaxCalculator.java │ │ ├── speed │ │ ├── Bio.java │ │ ├── IntelliJPlay.java │ │ ├── Person.java │ │ └── ReactiveHell.java │ │ └── support │ │ ├── AnotherService.java │ │ ├── CustomerProfile.java │ │ ├── colors │ │ ├── Blue.java │ │ ├── BlueRepo.java │ │ ├── Green.java │ │ ├── GreenRepo.java │ │ ├── Yellow.java │ │ └── YellowRepo.java │ │ └── dirty │ │ ├── Customer.java │ │ ├── Game.java │ │ ├── Movie.java │ │ └── Rental.java └── resources │ └── static │ └── index.html └── test ├── java ├── Asserting.java └── victor │ └── training │ └── intellij │ └── refactoring │ └── extract_delegate │ └── LargeServiceTest.java └── resources └── record-search.feature /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | .project 25 | /target/ 26 | .settings 27 | .idea 28 | .classpath 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #IntelliJ Tricks by Victor Rentea, Software Crafter and Trainer 2 | 3 | # Me 4 | - Doing workshops for companies throughout the world. 5 | https://victorrentea.ro 6 | 7 | - 17 years of java, 9 years of trainings and consultancy 8 | 9 | - Founder of the 2nd largest 10 | Software Crafter Community on Meetup.com (5K members): 11 | Join us 👉 https://victorrentea.ro/community 12 | 13 | 14 | # Hi, DevTernity ! 15 | 16 | ## First day driving ... 17 | 18 | ## Exploratory Refactoring 19 | 20 | ### Typing 21 | - Autocompletion: person.firstName > person.fn > p.fn 22 | - Boilerplate: toString 23 | - Type-aware / snake-completion: MaritalStatus 24 | - Postfix Completion: .sout .log .assertThat 25 | - Live Templates: boot, logs 26 | - TAB completion 27 | - Statics (CTRL-SPACE x 2): ctm 28 | 29 | ### Wrapping 30 | - Finish Statement (CTRL-SHIFT-ENTER :: ⇧⌘Enter) 31 | - if, method, class 32 | - method call: ofNullable( 33 | - Wrap generics: Optional< 34 | - Surround with (CTRL-ALT-T :: ⌥⌘T): if, try 35 | - Embrace Selection: while text is selected, press any of: {"'`<([ 36 | 37 | ### Smart Selecting 38 | - Multi-cursor 39 | - Token-based❤️ (ALT-J :: ^G) -- MovieType .html 40 | - ALT-drag -- .feature 41 | - ALT-SHIFT + click, click 42 | - Expand/Contract selection 43 | 44 | ### 👑 Quick Fix (aka Inspections) 45 | (ALT-ENTER :: ⌥ ⏎): 46 | - Define Variable for expression 47 | - Define new type/method 48 | - Delete dead code 49 | - Syntax-Tree analysis: see Boolean Logic 50 | - Run inspection on entire project -- String.valueOf 51 | - and 500+ more 😊=> almost all are disabled by default 52 | 53 | ### FP Support 54 | - ALT-Enter on .stream <-> for 55 | - Skip writing ".stream()" 56 | - Autocomplete after directly after :: 57 | - Collecting: ctl, cs, cj 58 | 59 | ### Code inspection / Surviving Legacy 60 | - Quick Definition (Ctrl-Shift-I :: ⌥ Space) 61 | - Current Parameter (Ctrl-P) 62 | - Type of current expression (Ctrl-Shift-P) 63 | - Call hierarchy (CTRL-ALT-H :: ^⌥H) 64 | - Recent Files (CTRL-E :: ⌘E) 65 | - Recent Places/Changes (CTRL-SHIFT-E) 66 | - Bookmark (F11 :: F3) 67 | - Collapse / Fold (CTRL-. :: ⌘.) 68 | 69 | ### Refactoring 70 | - Introduce Parameter, Functional Parameter, and Parameter Object -- Parameters.java 71 | - Add param from inside / from outside w/ ALT-ENTER 72 | 73 | - Extract Method (+ Auto-Parameterize) -- ExtractMethod.java 74 | - Combo: Extract over & Inline inner 75 | - Combo: Extract & Move/Convert to Instance 76 | 77 | - Extract / Inline / Encapsulate Field -- Fields.java 78 | - Extract explanatory variable (w or w/o preselecting) 79 | - Extract / Inline Interface 80 | 81 | 82 | ### Next Steps 83 | - Become a Shortcuts Ninja 🥷: install "Key Promoter X" plugin 84 | - Practice all the moves yourself (pause-play this) 85 | 86 | - More Inspections: Download my (opinionated) inspections list 87 | (search Aggressive_Refactoring.xml on https://victorrentea.ro) 88 | - In-house workshop your company won't ever forget 89 | mailto:victorrentea@gmail.com 90 | 91 | - Join my Community of Software Crafters (>5000 members) 92 | for monthly live webinars and hot🔥 debates -------------------------------------------------------------------------------- /intellij-tips.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | victor.training 5 | intellij-tips 6 | 0.0.1-SNAPSHOT 7 | 8 | 9 | 10 | org.springframework.boot 11 | spring-boot-starter 12 | 2.6.2 13 | 14 | 15 | org.junit.jupiter 16 | junit-jupiter 17 | 5.6.2 18 | compile 19 | 20 | 21 | org.projectlombok 22 | lombok 23 | 1.18.10 24 | 25 | 26 | javax.persistence 27 | javax.persistence-api 28 | 2.2 29 | 30 | 31 | commons-lang 32 | commons-lang 33 | 2.6 34 | 35 | 36 | org.assertj 37 | assertj-core 38 | 3.16.1 39 | 40 | 41 | org.slf4j 42 | slf4j-api 43 | 1.7.30 44 | 45 | 46 | io.projectreactor 47 | reactor-core 48 | 3.4.18 49 | compile 50 | 51 | 52 | 53 | 54 | 55 | org.apache.maven.plugins 56 | maven-compiler-plugin 57 | 3.8.1 58 | 59 | 17 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/refactoring/BooleanLogic.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.refactoring; 2 | 3 | public class BooleanLogic { 4 | 5 | 6 | public int deepMethod(int x) { 7 | int i; 8 | int j = 5; 9 | int k; 10 | int l = x; 11 | int result = 0; 12 | 13 | if (x > 0) { 14 | i = 1; 15 | if (x > i) { 16 | int k1; 17 | var result1 = result; 18 | k1 = x - 2; 19 | result1 = aaa(l, result1, k1); 20 | result = result1; 21 | } else { 22 | result = 3; 23 | } 24 | System.out.println("Send notification " + j); 25 | } else { 26 | result = 2; 27 | } 28 | return result; 29 | } 30 | 31 | private int aaa(int latitude, int result1, int k1) { 32 | for (int p = 0; p < k1; p++) { 33 | System.out.println("Halo " + latitude); 34 | latitude++; 35 | result1 = evenDeeper(latitude, result1, k1); 36 | } 37 | return result1; 38 | } 39 | 40 | private int evenDeeper(int l, int result, int k) { 41 | if (l == k) { 42 | result = 5; 43 | } 44 | return result; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/refactoring/ExtractMethod.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.refactoring; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import victor.training.intellij.support.AnotherService; 5 | import victor.training.intellij.support.CustomerProfile; 6 | 7 | @RequiredArgsConstructor 8 | class ExtractMethod { 9 | private final AnotherService anotherService; 10 | 11 | public void f(int n) { 12 | System.out.println("Logic F"); 13 | for (int i = 0; i < 4; i++) { 14 | if (n + i < 0) { 15 | sendMessage("Code " + i); 16 | } else { 17 | throw new IllegalArgumentException(); 18 | } 19 | } 20 | } 21 | public void g(int n) { 22 | System.out.println("Logic G"); 23 | try { 24 | for (int j = 0; j < 4; j++) { 25 | if (n + j < 0) { // Combo inner/outer 26 | sendMessage("Code" + j); 27 | } else { 28 | throw new IllegalArgumentException(); 29 | } 30 | } 31 | } catch (Exception e) { 32 | throw new RuntimeException("Rethrow", e); 33 | } 34 | } 35 | 36 | public void sendMessage(String message) { 37 | System.out.println(message); 38 | } 39 | 40 | public void businessLogic(CustomerProfile customer) { 41 | 42 | // Heavy business logic 43 | // Heavy business logic 44 | // Heavy business logic 45 | // Where can I move this bit of domain logic operating on the state of a single entity? 46 | int discountPercentage = 3; 47 | if (customer.isGoldMember()) { 48 | discountPercentage += 1; 49 | } 50 | System.out.println("Biz Logic with discount " + discountPercentage); 51 | // Heavy business logic 52 | // Heavy business logic 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/refactoring/Fields.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.refactoring; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | public class Fields { 6 | @Test 7 | public void test1() { 8 | DataObject data = new DataObject(); 9 | data.x = "xman"; 10 | new TestedClass().f(data); 11 | } 12 | @Test 13 | public void test2() { 14 | DataObject data = new DataObject(); 15 | data.x = "xwoman"; 16 | new TestedClass().f(data); 17 | } 18 | } 19 | 20 | class TestedClass { 21 | public void f(DataObject data) { 22 | String x = data.x.toUpperCase(); 23 | System.out.println(x); 24 | } 25 | } 26 | 27 | class DataObject { 28 | public String x; 29 | public String y; 30 | } 31 | 32 | // - extract field (Yuck: long-lived state, temporary field code smell) 33 | // - inline field 34 | // - encapsulate fields / inline accessors -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/refactoring/LocalVariables.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.refactoring; 2 | 3 | import victor.training.intellij.support.dirty.Movie; 4 | import victor.training.intellij.support.dirty.Rental; 5 | 6 | import java.util.List; 7 | 8 | public class LocalVariables { 9 | public int getFrequentRenterPoints(List rentals) { 10 | int frequentRenterPoints = 0; 11 | for (Rental rental : rentals) { 12 | // add frequent renter points 13 | frequentRenterPoints++; 14 | // add bonus for a two day new release rental 15 | if ((rental.getMovie().getCategory() == Movie.CATEGORY_NEW_RELEASE) 16 | && rental.getDaysRented() > 1) 17 | frequentRenterPoints++; 18 | } 19 | return frequentRenterPoints; 20 | } 21 | 22 | public static int discount(int price, int quantity) { 23 | if (price > 50) price = price - 2; 24 | if (quantity > 100) price = price - 1; 25 | return price; 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/refactoring/Parameters.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.refactoring; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | 5 | interface SomeRepo { 6 | int findById(int id); 7 | } 8 | @RequiredArgsConstructor 9 | public class Parameters { 10 | private final SomeRepo someRepo; 11 | public void method(int weeks, int devs) { 12 | System.out.println("Status report for project Colibri"); 13 | int days = weeks * 5; // work days per week 14 | System.out.println("Worked weeks " + weeks); 15 | int mandays = days * (devs - 1); 16 | try { 17 | System.out.println("Inner logic that has to change " + mandays); 18 | } catch (Exception e) { 19 | e.printStackTrace(); 20 | } 21 | } 22 | } 23 | 24 | class Caller1 { 25 | Parameters parameters; 26 | public void f(int weeks) { 27 | parameters.method(weeks, 4); 28 | } 29 | } 30 | 31 | class Caller2 { 32 | Parameters parameters; 33 | public void g(int weeks) { 34 | parameters.method(weeks, 3); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/refactoring/extract_delegate/LargeEntity.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.refactoring.extract_delegate; 2 | 3 | class ClientCode { 4 | public static void main(String[] args) { 5 | LargeEntity customer = new LargeEntity(); 6 | customer.setFirstName("John"); 7 | customer.setLastName("DOE"); 8 | customer.setCountry("Ch. Elysees"); 9 | 10 | displayGreeting(customer); 11 | displayFarewell(customer); 12 | } 13 | 14 | private static void displayGreeting(LargeEntity customer) { 15 | System.out.println("Hello " + customer.getFirstName() + " from " + customer.getCountry()); 16 | } 17 | 18 | private static void displayFarewell(LargeEntity customer) { 19 | System.out.println("Good bye " + customer.getFirstName()); 20 | } 21 | } 22 | // - Extract Delegate (grouping fields together) 23 | // - Remove Middleman 24 | 25 | public class LargeEntity { 26 | private String firstName; 27 | private String lastName; 28 | private String country; 29 | 30 | public String getFirstName() { 31 | return firstName; 32 | } 33 | 34 | public void setFirstName(String firstName) { 35 | this.firstName = firstName; 36 | } 37 | 38 | public String getLastName() { 39 | return lastName; 40 | } 41 | 42 | public void setLastName(String lastName) { 43 | this.lastName = lastName; 44 | } 45 | 46 | public String getCountry() { 47 | return country; 48 | } 49 | 50 | public void setCountry(String country) { 51 | this.country = country; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/refactoring/extract_delegate/LargeService.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.refactoring.extract_delegate; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Service; 5 | import victor.training.intellij.support.colors.*; 6 | 7 | @Service 8 | @RequiredArgsConstructor 9 | public class LargeService { 10 | private final YellowRepo yellowRepo; 11 | private final BlueRepo blueRepo; 12 | private final GreenRepo greenRepo; 13 | 14 | public void top1(long aId, long bId) { 15 | // extract me 16 | Yellow yellow = yellowRepo.findById(aId); 17 | Blue blue = blueRepo.findById(bId); 18 | int greenValue = yellow.getTotal() + blue.getTotal(); 19 | 20 | Green green = new Green(greenValue); 21 | greenRepo.save(green); 22 | } 23 | 24 | public int top2(long betaId) { 25 | Blue blue = blueRepo.findById(betaId); 26 | return blue.getTotal(); 27 | } 28 | } 29 | // - extract delegate 30 | // - inline delegate 31 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/refactoring/extract_interface/Service1.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.refactoring.extract_interface; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Service; 5 | 6 | @Service 7 | @RequiredArgsConstructor 8 | public class Service1 { 9 | private final TaxCalculator service; 10 | 11 | public void estimateCosts(int parcelValue) { 12 | int tax = service.computeTax(parcelValue); 13 | System.out.println(tax); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/refactoring/extract_interface/Service2.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.refactoring.extract_interface; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Service; 5 | 6 | 7 | @Service 8 | @RequiredArgsConstructor 9 | public class Service2 { 10 | private final TaxCalculator service; 11 | 12 | public void computeVAT(int parcelValue) { 13 | System.out.println("This too"); 14 | int tax = service.computeTax(parcelValue); 15 | System.out.println(tax); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/refactoring/extract_interface/TaxCalculator.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.refactoring.extract_interface; 2 | 3 | public class TaxCalculator { 4 | // TODO we have to support a new way to compute taxes 5 | public int computeTax(int parcelValue) { 6 | return parcelValue / 2; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/speed/Bio.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.speed; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | public class Bio { 6 | private LocalDateTime birthTime; 7 | 8 | public LocalDateTime getBirthTime() { 9 | return birthTime; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/speed/IntelliJPlay.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.speed; 2 | 3 | 4 | import victor.training.intellij.speed.Person.MaritalStatus; 5 | import victor.training.intellij.support.dirty.Customer; 6 | import victor.training.intellij.support.dirty.Rental; 7 | 8 | import java.time.LocalDateTime; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.Set; 12 | import java.util.stream.Stream; 13 | 14 | import static java.util.stream.Collectors.toList; 15 | import static java.util.stream.Collectors.toSet; 16 | import static org.assertj.core.api.Assertions.assertThat; 17 | 18 | 19 | public class IntelliJPlay { 20 | public static void main(String[] args) { 21 | Person person = new Person(); 22 | 23 | Customer customer = new Customer(); 24 | List list = new ArrayList<>(); 25 | for (Rental rental : customer.getRentals()) { 26 | list.add(rental.getDaysRented()); 27 | } 28 | System.out.println(list); 29 | method(customer.getRentals()); 30 | } 31 | 32 | public static void introduce(String firstName, MaritalStatus maritalStatus) { 33 | System.out.println("This is " + firstName + (maritalStatus == MaritalStatus.SINGLE ? "😉" : "")); 34 | } 35 | 36 | 37 | public static void method(List rentals) { 38 | rentals.clear(); 39 | } 40 | 41 | 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/speed/Person.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.speed; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.List; 5 | import java.util.Optional; 6 | 7 | 8 | // typical Java Bean (1997) 9 | public class Person { 10 | enum MaritalStatus { 11 | MARRIED, 12 | SINGLE, 13 | DIVORCED, 14 | WHATEVER 15 | } 16 | 17 | private String id; 18 | private String firstName; 19 | private String firstLetter; 20 | private String lastName; 21 | private String phone; // nullable in DB 22 | private LocalDateTime createTime; 23 | private Bio bio; 24 | private List addresses; 25 | private MaritalStatus maritalStatus; 26 | 27 | public List getAddresses() { 28 | return addresses; 29 | } 30 | 31 | public MaritalStatus getMaritalStatus() { 32 | return maritalStatus; 33 | } 34 | 35 | public String getFirstLetter() { 36 | return firstLetter; 37 | } 38 | 39 | public void setBio(Bio bio) { 40 | this.bio = bio; 41 | } 42 | 43 | public Bio getBio() { 44 | return bio; 45 | } 46 | 47 | public LocalDateTime getCreateTime() { 48 | return createTime; 49 | } 50 | 51 | public Person setCreateTime(LocalDateTime createTime) { 52 | this.createTime = createTime; 53 | return this; 54 | } 55 | 56 | public Person setMaritalStatus(MaritalStatus maritalStatus) { 57 | this.maritalStatus = maritalStatus; 58 | return this; 59 | } 60 | 61 | public Optional getPhone() { 62 | return Optional.ofNullable(phone); 63 | } 64 | 65 | public String getId() { 66 | return id; 67 | } 68 | 69 | public void setId(String id) { 70 | this.id = id; 71 | } 72 | 73 | public String getFirstName() { 74 | return firstName; 75 | } 76 | 77 | public void setFirstName(String firstName) { 78 | this.firstName = firstName; 79 | } 80 | 81 | public String getLastName() { 82 | return lastName; 83 | } 84 | 85 | public void setLastName(String lastName) { 86 | this.lastName = lastName; 87 | } 88 | 89 | 90 | public void setPhone(String phone) { 91 | this.phone = phone; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/speed/ReactiveHell.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.speed; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Value; 5 | import lombok.With; 6 | import reactor.core.publisher.Mono; 7 | 8 | public class ReactiveHell { 9 | public ReactiveHell(Dependency dependency) { 10 | this.dependency = dependency; 11 | } 12 | 13 | static class A { 14 | } 15 | 16 | static class B { 17 | } 18 | 19 | static class C { 20 | } 21 | 22 | static class D { 23 | } 24 | 25 | @Value 26 | @With 27 | static class AB { 28 | public A a; 29 | public B b; 30 | } 31 | 32 | @Value 33 | static class ABC { 34 | public A a; 35 | public B b; 36 | public C c; 37 | } 38 | 39 | interface Dependency { 40 | Mono a(int id); 41 | 42 | Mono b(int id); 43 | 44 | Mono b1(A a); 45 | 46 | Mono c(int id); 47 | 48 | Mono c1(A a); 49 | 50 | Mono c2(A a, B b); 51 | 52 | Mono d(int id); 53 | 54 | Mono saveA(A a); 55 | 56 | Mono auditA(A a1, A a0); 57 | } 58 | 59 | protected final Dependency dependency; 60 | 61 | @Value // imutable object 62 | @With // public P10UseCaseContext withA(A newa) { return new P10UseCaseContext(newa, b,c,d); } 63 | @AllArgsConstructor 64 | static class P10UseCaseContext { 65 | int id; 66 | A a; 67 | B b; 68 | C c; 69 | D d; 70 | 71 | public P10UseCaseContext(int id) { // initial UC parameters 72 | this(id, null, null, null, null); 73 | } 74 | } 75 | 76 | 77 | public Mono nestedLambdas3(int id) { 78 | return dependency.a(id).flatMap(a -> dependency.b1(a).flatMap(b -> dependency.c2(a, b).map(c -> new ABC(a, b, c)))); 79 | } 80 | 81 | public Mono reactivePainChain(int id) { 82 | return dependency.a(id).zipWith(dependency.d(id), 83 | (a, d) -> new P10UseCaseContext(id).withA(a).withD(d)) 84 | .flatMap(context -> dependency.b1(context.getA()).map(context::withB)) 85 | .flatMap(context -> dependency.c2(context.getA(), context.getB()).map(context::withC)); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/support/AnotherService.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.support; 2 | 3 | public class AnotherService { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/support/CustomerProfile.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.support; 2 | 3 | import lombok.Data; 4 | 5 | @Data // errorum humanum est 6 | public class CustomerProfile { 7 | private String name; 8 | private boolean goldMember; 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/support/colors/Blue.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.support.colors; 2 | 3 | public class Blue { 4 | public int getTotal() { 5 | return 0; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/support/colors/BlueRepo.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.support.colors; 2 | 3 | public interface BlueRepo { 4 | Blue findById(long id); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/support/colors/Green.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.support.colors; 2 | 3 | public class Green { 4 | public Green(int ab) { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/support/colors/GreenRepo.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.support.colors; 2 | 3 | public interface GreenRepo { 4 | void save(Green green); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/support/colors/Yellow.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.support.colors; 2 | 3 | public class Yellow { 4 | public int getTotal() { 5 | return 0; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/support/colors/YellowRepo.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.support.colors; 2 | 3 | public interface YellowRepo { 4 | Yellow findById(long id); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/support/dirty/Customer.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.support.dirty; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | 8 | public class Customer { 9 | private final List rentals = new ArrayList<>(); 10 | 11 | public List getRentals() { 12 | return Collections.unmodifiableList(rentals); 13 | } 14 | 15 | public String generateStatement(String customerName, List rentals) { 16 | double totalPrice = 0; 17 | Iterator rentalsIt = rentals.iterator(); 18 | String result = "Rental Record for " + customerName + "\n"; 19 | while (rentalsIt.hasNext()) { 20 | Rental rental = rentalsIt.next(); 21 | double price = 0;// TODO get from Rental 22 | // TODO result += formatStatementLine(..) 23 | totalPrice += price; 24 | } 25 | 26 | result += "Amount owed is " + String.valueOf(totalPrice) + "\n"; 27 | return result; 28 | } 29 | 30 | public String formatStatementLine(Movie movie, double price) { 31 | return "\t" + movie.getTitle() + "\t" + String.valueOf(price) + "\n"; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/support/dirty/Game.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.support.dirty; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | 6 | // TODO refactor me 7 | public class Game { 8 | ArrayList players = new ArrayList(); 9 | int[] places = new int[6]; 10 | int[] purses = new int[6]; 11 | boolean[] inPenaltyBox = new boolean[6]; 12 | 13 | LinkedList popQuestions = new LinkedList(); 14 | LinkedList scienceQuestions = new LinkedList(); 15 | LinkedList sportsQuestions = new LinkedList(); 16 | LinkedList rockQuestions = new LinkedList(); 17 | 18 | int currentPlayer = 0; 19 | boolean isGettingOutOfPenaltyBox; 20 | 21 | public Game() { 22 | for (int i = 0; i < 50; i++) { 23 | popQuestions.addLast("Pop Question " + i); 24 | scienceQuestions.addLast(("Science Question " + i)); 25 | sportsQuestions.addLast(("Sports Question " + i)); 26 | rockQuestions.addLast(createRockQuestion(i)); 27 | } 28 | } 29 | 30 | public String createRockQuestion(int index) { 31 | return "Rock Question " + index; 32 | } 33 | 34 | public boolean isPlayable() { 35 | return (howManyPlayers() >= 2); 36 | } 37 | 38 | public boolean add(String playerName) { 39 | 40 | 41 | players.add(playerName); 42 | places[howManyPlayers()] = 0; 43 | purses[howManyPlayers()] = 0; 44 | inPenaltyBox[howManyPlayers()] = false; 45 | 46 | System.out.println(playerName + " was added"); 47 | System.out.println("They are player number " + players.size()); 48 | return true; 49 | } 50 | 51 | public int howManyPlayers() { 52 | return players.size(); 53 | } 54 | 55 | public void roll(int roll) { 56 | System.out.println(players.get(currentPlayer) + " is the current player"); 57 | System.out.println("They have rolled a " + roll); 58 | 59 | if (inPenaltyBox[currentPlayer]) { 60 | if (roll % 2 != 0) { 61 | isGettingOutOfPenaltyBox = true; 62 | 63 | System.out.println(players.get(currentPlayer) + " is getting out of the penalty box"); 64 | places[currentPlayer] = places[currentPlayer] + roll; 65 | if (places[currentPlayer] > 11) places[currentPlayer] = places[currentPlayer] - 12; 66 | 67 | System.out.println(players.get(currentPlayer) 68 | + "'s new location is " 69 | + places[currentPlayer]); 70 | System.out.println("The category is " + currentCategory()); 71 | askQuestion(); 72 | } else { 73 | System.out.println(players.get(currentPlayer) + " is not getting out of the penalty box"); 74 | isGettingOutOfPenaltyBox = false; 75 | } 76 | 77 | } else { 78 | 79 | places[currentPlayer] = places[currentPlayer] + roll; 80 | if (places[currentPlayer] > 11) places[currentPlayer] = places[currentPlayer] - 12; 81 | 82 | System.out.println(players.get(currentPlayer) 83 | + "'s new location is " 84 | + places[currentPlayer]); 85 | System.out.println("The category is " + currentCategory()); 86 | askQuestion(); 87 | } 88 | 89 | } 90 | 91 | private void askQuestion() { 92 | if (currentCategory() == "Pop") 93 | System.out.println(popQuestions.removeFirst()); 94 | if (currentCategory() == "Science") 95 | System.out.println(scienceQuestions.removeFirst()); 96 | if (currentCategory() == "Sports") 97 | System.out.println(sportsQuestions.removeFirst()); 98 | if (currentCategory() == "Rock") 99 | System.out.println(rockQuestions.removeFirst()); 100 | } 101 | 102 | 103 | private String currentCategory() { 104 | if (places[currentPlayer] == 0) return "Pop"; 105 | if (places[currentPlayer] == 4) return "Pop"; 106 | if (places[currentPlayer] == 8) return "Pop"; 107 | if (places[currentPlayer] == 1) return "Science"; 108 | if (places[currentPlayer] == 5) return "Science"; 109 | if (places[currentPlayer] == 9) return "Science"; 110 | if (places[currentPlayer] == 2) return "Sports"; 111 | if (places[currentPlayer] == 6) return "Sports"; 112 | if (places[currentPlayer] == 10) return "Sports"; 113 | return "Rock"; 114 | } 115 | 116 | public boolean wasCorrectlyAnswered() { 117 | if (inPenaltyBox[currentPlayer]) { 118 | if (isGettingOutOfPenaltyBox) { 119 | System.out.println("Answer was correct!!!!"); 120 | purses[currentPlayer]++; 121 | System.out.println(players.get(currentPlayer) 122 | + " now has " 123 | + purses[currentPlayer] 124 | + " Gold Coins."); 125 | 126 | boolean winner = didPlayerWin(); 127 | currentPlayer++; 128 | if (currentPlayer == players.size()) currentPlayer = 0; 129 | 130 | return winner; 131 | } else { 132 | currentPlayer++; 133 | if (currentPlayer == players.size()) currentPlayer = 0; 134 | return true; 135 | } 136 | } else { 137 | System.out.println("Answer was corrent!!!!"); 138 | purses[currentPlayer]++; 139 | System.out.println(players.get(currentPlayer) 140 | + " now has " 141 | + purses[currentPlayer] 142 | + " Gold Coins."); 143 | 144 | boolean winner = didPlayerWin(); 145 | currentPlayer++; 146 | if (currentPlayer == players.size()) currentPlayer = 0; 147 | 148 | return winner; 149 | } 150 | } 151 | 152 | public boolean wrongAnswer() { 153 | System.out.println("Question was incorrectly answered"); 154 | System.out.println(players.get(currentPlayer) + " was sent to the penalty box"); 155 | inPenaltyBox[currentPlayer] = true; 156 | 157 | currentPlayer++; 158 | if (currentPlayer == players.size()) currentPlayer = 0; 159 | return true; 160 | } 161 | 162 | 163 | private boolean didPlayerWin() { 164 | return !(purses[currentPlayer] == 6); 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/support/dirty/Movie.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.support.dirty; 2 | 3 | public class Movie { 4 | public static final int CATEGORY_CHILDRENS = 2; 5 | public static final int CATEGORY_REGULAR = 0; 6 | public static final int CATEGORY_NEW_RELEASE = 1; 7 | 8 | enum MovieType { 9 | // TODO create from constants 10 | } 11 | 12 | private String title; 13 | private int category; 14 | 15 | public Movie(String title, int category) { 16 | this.title = title; 17 | this.category = category; 18 | } 19 | 20 | public int getCategory() { 21 | return category; 22 | } 23 | 24 | public void setCategory(int arg) { 25 | category = arg; 26 | } 27 | 28 | public String getTitle() { 29 | return title; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /src/main/java/victor/training/intellij/support/dirty/Rental.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.support.dirty; 2 | public class Rental { 3 | private final Movie movie; 4 | private final int daysRented; 5 | 6 | public Rental(Movie movie, int daysRented) { 7 | this.movie = movie; 8 | this.daysRented = daysRented; 9 | } 10 | 11 | public int getDaysRented() { 12 | return daysRented; 13 | } 14 | 15 | public Movie getMovie() { 16 | return movie; 17 | } 18 | 19 | public double computePrice() { 20 | double price = 0; 21 | switch (getMovie().getCategory()) { 22 | case Movie.CATEGORY_REGULAR: 23 | price = 2; 24 | if (daysRented > 2) 25 | price += (daysRented - 2) * 1.5; 26 | break; 27 | case Movie.CATEGORY_NEW_RELEASE: 28 | price = daysRented * 3; 29 | break; 30 | case Movie.CATEGORY_CHILDRENS: 31 | price = 1.5; 32 | break; 33 | } 34 | return price; 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 17 | 18 | 19 | 20 | 21 |

Single Page Application

22 |

Hello,

23 | 24 | 25 |
26 |
27 |
28 |
29 | 30 |
31 | 32 | 33 |
Training NameStart DateTeacherOps
34 | 35 | 36 |
37 | 38 | 48 | 49 | 59 | 60 |
63 | 67 | 68 | 263 | 264 | 265 | -------------------------------------------------------------------------------- /src/test/java/Asserting.java: -------------------------------------------------------------------------------- 1 | import org.assertj.core.api.Assertions; 2 | import org.junit.jupiter.api.Test; 3 | 4 | import static org.assertj.core.api.Assertions.assertThat; 5 | 6 | public class Asserting { 7 | @Test 8 | void test() { 9 | int actual = testedCode(); 10 | int expected = 1; 11 | 12 | assertThat(actual).isEqualTo(expected); 13 | } 14 | 15 | private int testedCode() { 16 | return 1; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/victor/training/intellij/refactoring/extract_delegate/LargeServiceTest.java: -------------------------------------------------------------------------------- 1 | package victor.training.intellij.refactoring.extract_delegate; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | class LargeServiceTest { 8 | 9 | private LargeService largeService; 10 | 11 | @Test 12 | void top1() { 13 | largeService.top1(1L, 2L); 14 | } 15 | 16 | @Test 17 | void top2() { 18 | int v = largeService.top2(1L); 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/resources/record-search.feature: -------------------------------------------------------------------------------- 1 | #Keywords Summary : 2 | #Feature: List of scenarios. 3 | #Scenario: Business rule through list of steps with arguments. 4 | #Given: Some precondition step 5 | #When: Some key actions 6 | #Then: To observe outcomes or validation 7 | #And,But: To enumerate more Given,When,Then steps 8 | #Scenario Outline: List of steps for data-driven as an Examples and 9 | #Examples: Container for s table 10 | #Background: List of steps run before each of the scenarios 11 | #""" (Doc Strings) 12 | #| (Data Tables) 13 | #@ (Tags/Labels):To group Scenarios 14 | #<> (placeholder) 15 | #"" 16 | ## (Comments) 17 | @txn 18 | Feature: Records Search 19 | Background: Insert standard data 20 | Scenario Outline: Search for an Active Record by Version 21 | Given A Record with regliss reference "001.1.000001" with the following names in versions 22 | | V1 | V2 | V3 | V4 | 23 | | a1 | a2 | b | b | 24 | When criteria record name "" 25 | And criteria version number 26 | And include historical records "" 27 | And include inactive records "" 28 | Then the results have versions "" 29 | And the row has regliss reference "001.1.000001" 30 | 31 | #a1 is inactive in V2; a2 is inactive in V3 32 | #inactive=true + hist=false will return a result only if the rec is INACTIVE in the LAST version 33 | # the change of name is NOT deactivation of Record 34 | Examples: 35 | | searchName | searchVerNo | includeHistorical | includeInactive | rowVersions | 36 | | b | | true | true | 3,4 | 37 | | b | | true | false | 3,4 | 38 | | b | | false | false | 4 | 39 | | b | | false | true | 4 | 40 | | b | 3 | false | false | 3 | 41 | | b | 3 | false | true | 3 | 42 | | b | 3 | true | false | 3 | 43 | | b | 3 | true | true | 3 | 44 | | a% | | false | true | | 45 | | a% | | false | false | | 46 | | a% | | true | false | 1,2 | 47 | | a% | | true | true | 1,2 | 48 | | a% | 1 | false | false | 1 | 49 | | a% | 1 | false | true | 1 | 50 | | a% | 1 | true | false | 1 | 51 | | a% | 1 | true | true | 1 | 52 | 53 | Scenario Outline: Search for an Inactive Record by Version 54 | Given A Record with regliss reference "001.1.000001" with the following names in versions 55 | | V1 | V2 | V3 | V4 | 56 | | a1 | a2 | b | | 57 | When criteria record name "" 58 | And criteria version number 59 | And include historical records "" 60 | And include inactive records "" 61 | Then the results have versions "" 62 | And the row has regliss reference "001.1.000001" 63 | 64 | #b is Active in V3 65 | #b is Inactive in V4 66 | #b is NOT present in V5 67 | # 68 | #Historical = look also in versions before the last one 69 | #Inactive = record is inactive in the version returned 70 | # 71 | Examples: 72 | | searchName | searchVerNo | includeHistorical | includeInactive | rowVersions | 73 | | b | | true | true | 3,4 | 74 | | b | | false | true | 4 | 75 | | b | | true | false | 3 | 76 | | b | | false | false | | 77 | | b | 3 | false | true | 3 | 78 | | b | 3 | true | true | 3 | 79 | | b | 3 | false | false | 3 | 80 | | b | 3 | true | false | 3 | 81 | | a% | | true | true | 1,2 | 82 | | a% | | false | true | | 83 | | a% | | true | false | 1,2 | 84 | | a% | | false | false | | 85 | | a% | 1 | false | true | 1 | 86 | | a% | 1 | true | true | 1 | 87 | | a% | 1 | false | false | 1 | 88 | | a% | 1 | true | false | 1 | 89 | 90 | Scenario Outline: Search for an Active Record by Version and activity interval 91 | Given A Record with regliss reference "001.1.000001" with the following names in versions 92 | | V1 | V2 | V3 | V4 | 93 | | a1 | a2 | b | b | 94 | | 2016-01-03 09:00 | 2016-01-10 09:00 | 2016-01-20 09:00 | 2016-01-29 00:00 | 95 | When criteria record name "" 96 | And criteria version number 97 | And include historical records "" 98 | And record active from "2016-01-" 99 | And record active to "2016-01-" 100 | Then the results have versions "" 101 | And the row has regliss reference "001.1.000001" 102 | 103 | Examples: 104 | | searchName | searchVerNo | from | to | includeHistorical | rowVersions | 105 | | b | | 29 | 29 | true | 4 | 106 | | b | | 29 | 29 | false | 4 | 107 | | b | | 30 | 31 | false | 4 | 108 | | b | 3 | 20 | 29 | true | 3 | 109 | | b | 3 | 30 | 31 | true | | 110 | | a% | | 10 | 10 | true | 1,2 | 111 | | a% | | 01 | 09 | true | 1 | 112 | | a% | | 20 | 30 | true | 2 | 113 | | a% | | 11 | 18 | true | 2 | 114 | | a% | 1 | 10 | 10 | true | 1 | 115 | | a% | 1 | 01 | 09 | true | 1 | 116 | | a% | 1 | 20 | 30 | true | | 117 | | a% | 1 | 03 | 03 | true | 1 | 118 | | a% | 1 | 11 | 19 | true | | 119 | | a% | 1 | 01 | 09 | true | 1 | 120 | | b | | 30 | 31 | true | 4 | 121 | 122 | Scenario Outline: Search for an Inactive Record by Version and activity interval 123 | Given A Record with regliss reference "001.1.000001" with the following names in versions 124 | | V1 | V2 | V3 | V4 | 125 | | a1 | a2 | b | | 126 | | 2016-01-03 09:00 | 2016-01-10 09:00 | 2016-01-20 09:00 | 2016-01-29 00:00 | 127 | When criteria record name "" 128 | And criteria version number 129 | And include inactive records "true" 130 | And include historical records "true" 131 | And record active from "2016-01-" 132 | And record active to "2016-01-" 133 | Then the results have versions "" 134 | And the row has regliss reference "001.1.000001" 135 | 136 | Examples: 137 | | searchName | searchVerNo | from | to | rowVersions | 138 | | b | | 20 | 20 | 3 | 139 | | b | | 30 | 30 | 4 | 140 | | b | 3 | 20 | 29 | 3 | 141 | | b | 3 | 30 | 30 | | 142 | | a% | | 10 | 10 | 1,2 | 143 | | a% | | 01 | 09 | 1 | 144 | | a% | | 20 | 30 | 2 | 145 | | a% | | 11 | 19 | 2 | 146 | | a% | 1 | 10 | 10 | 1 | 147 | | a% | 1 | 01 | 09 | 1 | 148 | | a% | 1 | 20 | 30 | | 149 | | a% | 1 | 03 | 03 | 1 | 150 | | a% | 1 | 11 | 19 | | 151 | | b | | 25 | 30 | 3,4 | 152 | --------------------------------------------------------------------------------