diff --git a/autovalue-tutorial/pom.xml b/autovalue-tutorial/pom.xml new file mode 100644 index 0000000000..37d595dce1 --- /dev/null +++ b/autovalue-tutorial/pom.xml @@ -0,0 +1,36 @@ + + 4.0.0 + com.baeldung + autovalue-tutorial + 1.0 + AutoValue + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 7 + 7 + + + + + + + com.google.auto.value + auto-value + 1.2 + + + + junit + junit + 4.3 + test + + + + diff --git a/autovalue-tutorial/src/main/java/com/baeldung/autovalue/AutoValueMoney.java b/autovalue-tutorial/src/main/java/com/baeldung/autovalue/AutoValueMoney.java new file mode 100644 index 0000000000..ef39f499d1 --- /dev/null +++ b/autovalue-tutorial/src/main/java/com/baeldung/autovalue/AutoValueMoney.java @@ -0,0 +1,15 @@ +package com.baeldung.autovalue; + +import com.google.auto.value.AutoValue; + +@AutoValue +public abstract class AutoValueMoney { + public abstract String getCurrency(); + + public abstract long getAmount(); + + public static AutoValueMoney create(String currency, long amount) { + return new AutoValue_AutoValueMoney(currency, amount); + + } +} diff --git a/autovalue-tutorial/src/main/java/com/baeldung/autovalue/AutoValueMoneyWithBuilder.java b/autovalue-tutorial/src/main/java/com/baeldung/autovalue/AutoValueMoneyWithBuilder.java new file mode 100644 index 0000000000..a7ac93e45b --- /dev/null +++ b/autovalue-tutorial/src/main/java/com/baeldung/autovalue/AutoValueMoneyWithBuilder.java @@ -0,0 +1,23 @@ +package com.baeldung.autovalue; + +import com.google.auto.value.AutoValue; + +@AutoValue +public abstract class AutoValueMoneyWithBuilder { + public abstract String getCurrency(); + + public abstract long getAmount(); + + static Builder builder() { + return new AutoValue_AutoValueMoneyWithBuilder.Builder(); + } + + @AutoValue.Builder + abstract static class Builder { + abstract Builder setCurrency(String currency); + + abstract Builder setAmount(long amount); + + abstract AutoValueMoneyWithBuilder build(); + } +} diff --git a/autovalue-tutorial/src/main/java/com/baeldung/autovalue/Foo.java b/autovalue-tutorial/src/main/java/com/baeldung/autovalue/Foo.java new file mode 100644 index 0000000000..bb90070f6d --- /dev/null +++ b/autovalue-tutorial/src/main/java/com/baeldung/autovalue/Foo.java @@ -0,0 +1,51 @@ +package com.baeldung.autovalue; + +import java.util.Objects; + +public final class Foo { + private final String text; + private final int number; + + public Foo(String text, int number) { + this.text = text; + this.number = number; + } + + public String getText() { + return text; + } + + public int getNumber() { + return number; + } + + @Override + public int hashCode() { + return Objects.hash(text, number); + } + + @Override + public String toString() { + return "Foo [text=" + text + ", number=" + number + "]"; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Foo other = (Foo) obj; + if (number != other.number) + return false; + if (text == null) { + if (other.text != null) + return false; + } else if (!text.equals(other.text)) + return false; + return true; + } + +} diff --git a/autovalue-tutorial/src/main/java/com/baeldung/autovalue/ImmutableMoney.java b/autovalue-tutorial/src/main/java/com/baeldung/autovalue/ImmutableMoney.java new file mode 100644 index 0000000000..04d29b6b09 --- /dev/null +++ b/autovalue-tutorial/src/main/java/com/baeldung/autovalue/ImmutableMoney.java @@ -0,0 +1,52 @@ +package com.baeldung.autovalue; +public final class ImmutableMoney { + private final long amount; + private final String currency; + public ImmutableMoney(long amount, String currency) { + this.amount = amount; + this.currency = currency; + } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (amount ^ (amount >>> 32)); + result = prime * result + + ((currency == null) ? 0 : currency.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ImmutableMoney other = (ImmutableMoney) obj; + if (amount != other.amount) + return false; + if (currency == null) { + if (other.currency != null) + return false; + } else if (!currency.equals(other.currency)) + return false; + return true; + } + + public long getAmount() { + return amount; + } + + public String getCurrency() { + return currency; + } + + @Override + public String toString() { + return "ImmutableMoney [amount=" + amount + ", currency=" + currency + + "]"; + } + +} diff --git a/autovalue-tutorial/src/main/java/com/baeldung/autovalue/MutableMoney.java b/autovalue-tutorial/src/main/java/com/baeldung/autovalue/MutableMoney.java new file mode 100644 index 0000000000..6cf8b75f7d --- /dev/null +++ b/autovalue-tutorial/src/main/java/com/baeldung/autovalue/MutableMoney.java @@ -0,0 +1,35 @@ +package com.baeldung.autovalue; + +public class MutableMoney { + @Override + public String toString() { + return "MutableMoney [amount=" + amount + ", currency=" + currency + + "]"; + } + + public long getAmount() { + return amount; + } + + public void setAmount(long amount) { + this.amount = amount; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + private long amount; + private String currency; + + public MutableMoney(long amount, String currency) { + super(); + this.amount = amount; + this.currency = currency; + } + +} diff --git a/autovalue-tutorial/src/test/java/com/baeldung/autovalue/MoneyTest.java b/autovalue-tutorial/src/test/java/com/baeldung/autovalue/MoneyTest.java new file mode 100644 index 0000000000..af3afe84fb --- /dev/null +++ b/autovalue-tutorial/src/test/java/com/baeldung/autovalue/MoneyTest.java @@ -0,0 +1,59 @@ +package com.baeldung.autovalue; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class MoneyTest { + @Test + public void givenTwoSameValueMoneyObjects_whenEqualityTestFails_thenCorrect() { + MutableMoney m1 = new MutableMoney(10000, "USD"); + MutableMoney m2 = new MutableMoney(10000, "USD"); + assertFalse(m1.equals(m2)); + } + + @Test + public void givenTwoSameValueMoneyValueObjects_whenEqualityTestPasses_thenCorrect() { + ImmutableMoney m1 = new ImmutableMoney(10000, "USD"); + ImmutableMoney m2 = new ImmutableMoney(10000, "USD"); + assertTrue(m1.equals(m2)); + } + + @Test + public void givenValueTypeWithAutoValue_whenFieldsCorrectlySet_thenCorrect() { + AutoValueMoney m = AutoValueMoney.create("USD", 10000); + assertEquals(m.getAmount(), 10000); + assertEquals(m.getCurrency(), "USD"); + } + + @Test + public void given2EqualValueTypesWithAutoValue_whenEqual_thenCorrect() { + AutoValueMoney m1 = AutoValueMoney.create("USD", 5000); + AutoValueMoney m2 = AutoValueMoney.create("USD", 5000); + assertTrue(m1.equals(m2)); + } + @Test + public void given2DifferentValueTypesWithAutoValue_whenNotEqual_thenCorrect() { + AutoValueMoney m1 = AutoValueMoney.create("GBP", 5000); + AutoValueMoney m2 = AutoValueMoney.create("USD", 5000); + assertFalse(m1.equals(m2)); + } + @Test + public void given2EqualValueTypesWithBuilder_whenEqual_thenCorrect() { + AutoValueMoneyWithBuilder m1 = AutoValueMoneyWithBuilder.builder().setAmount(5000).setCurrency("USD").build(); + AutoValueMoneyWithBuilder m2 = AutoValueMoneyWithBuilder.builder().setAmount(5000).setCurrency("USD").build(); + assertTrue(m1.equals(m2)); + } + @Test + public void given2DifferentValueTypesBuilder_whenNotEqual_thenCorrect() { + AutoValueMoneyWithBuilder m1 = AutoValueMoneyWithBuilder.builder().setAmount(5000).setCurrency("USD").build(); + AutoValueMoneyWithBuilder m2 = AutoValueMoneyWithBuilder.builder().setAmount(5000).setCurrency("GBP").build(); + assertFalse(m1.equals(m2)); + } + @Test + public void givenValueTypeWithBuilder_whenFieldsCorrectlySet_thenCorrect() { + AutoValueMoneyWithBuilder m = AutoValueMoneyWithBuilder.builder().setAmount(5000).setCurrency("USD").build(); + assertEquals(m.getAmount(), 5000); + assertEquals(m.getCurrency(), "USD"); + } +} diff --git a/dozer-tutorial/pom.xml b/dozer-tutorial/pom.xml new file mode 100644 index 0000000000..9447a3ff54 --- /dev/null +++ b/dozer-tutorial/pom.xml @@ -0,0 +1,59 @@ + + 4.0.0 + com.baeldung + dozer-tutorial + 1.0 + Dozer + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 7 + 7 + + + + + + + org.slf4j + slf4j-api + 1.7.5 + + + + org.slf4j + jcl-over-slf4j + 1.7.5 + + + + org.apache.commons + commons-lang3 + 3.2.1 + + + + commons-beanutils + commons-beanutils + 1.9.1 + + + + net.sf.dozer + dozer + 5.5.1 + + + junit + junit + 4.3 + test + + + + diff --git a/dozer-tutorial/src/main/java/com/baeldung/dozer/Dest.java b/dozer-tutorial/src/main/java/com/baeldung/dozer/Dest.java new file mode 100644 index 0000000000..26ba7e3ac4 --- /dev/null +++ b/dozer-tutorial/src/main/java/com/baeldung/dozer/Dest.java @@ -0,0 +1,33 @@ +package com.baeldung.dozer; + +public class Dest { + private String name; + private int age; + + public Dest() { + + } + + public Dest(String name, int age) { + super(); + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/dozer-tutorial/src/main/java/com/baeldung/dozer/Dest2.java b/dozer-tutorial/src/main/java/com/baeldung/dozer/Dest2.java new file mode 100644 index 0000000000..aa969b38d6 --- /dev/null +++ b/dozer-tutorial/src/main/java/com/baeldung/dozer/Dest2.java @@ -0,0 +1,38 @@ +package com.baeldung.dozer; + +public class Dest2 { + private int id; + private int points; + + public Dest2() { + + } + + public Dest2(int id, int points) { + super(); + this.id = id; + this.points = points; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getPoints() { + return points; + } + + public void setPoints(int points) { + this.points = points; + } + + @Override + public String toString() { + return "Dest2 [id=" + id + ", points=" + points + "]"; + } + +} diff --git a/dozer-tutorial/src/main/java/com/baeldung/dozer/MyCustomConvertor.java b/dozer-tutorial/src/main/java/com/baeldung/dozer/MyCustomConvertor.java new file mode 100644 index 0000000000..ae0ed0ba87 --- /dev/null +++ b/dozer-tutorial/src/main/java/com/baeldung/dozer/MyCustomConvertor.java @@ -0,0 +1,48 @@ +package com.baeldung.dozer; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.dozer.CustomConverter; +import org.dozer.MappingException; + +public class MyCustomConvertor implements CustomConverter { + + @Override + public Object convert(Object dest, Object source, Class arg2, + Class arg3) { + if (source == null) { + return null; + } + if (source instanceof Personne3) { + Personne3 person = (Personne3) source; + Date date = new Date(person.getDtob()); + DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + String isoDate = format.format(date); + return new Person3(person.getName(), isoDate); + + } else if (source instanceof Person3) { + Person3 person = (Person3) source; + DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + Date date = null; + try { + date = format.parse(person.getDtob()); + + } catch (ParseException e) { + throw new MappingException("Converter MyCustomConvertor " + + "used incorrectly:" + e.getMessage()); + } + long timestamp = date.getTime(); + return new Personne3(person.getName(), timestamp); + + } else { + throw new MappingException("Converter MyCustomConvertor " + + "used incorrectly. Arguments passed in were:" + dest + + " and " + source); + + } + } + +} diff --git a/dozer-tutorial/src/main/java/com/baeldung/dozer/Person.java b/dozer-tutorial/src/main/java/com/baeldung/dozer/Person.java new file mode 100644 index 0000000000..7367541951 --- /dev/null +++ b/dozer-tutorial/src/main/java/com/baeldung/dozer/Person.java @@ -0,0 +1,43 @@ +package com.baeldung.dozer; + +public class Person { + private String name; + private String nickname; + private int age; + + public Person() { + + } + + public Person(String name, String nickname, int age) { + super(); + this.name = name; + this.nickname = nickname; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/dozer-tutorial/src/main/java/com/baeldung/dozer/Person2.java b/dozer-tutorial/src/main/java/com/baeldung/dozer/Person2.java new file mode 100644 index 0000000000..1920f2868c --- /dev/null +++ b/dozer-tutorial/src/main/java/com/baeldung/dozer/Person2.java @@ -0,0 +1,43 @@ +package com.baeldung.dozer; + +public class Person2 { + private String name; + private String nickname; + private int age; + + public Person2() { + + } + + public Person2(String name, String nickname, int age) { + super(); + this.name = name; + this.nickname = nickname; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/dozer-tutorial/src/main/java/com/baeldung/dozer/Person3.java b/dozer-tutorial/src/main/java/com/baeldung/dozer/Person3.java new file mode 100644 index 0000000000..ae1e610aa2 --- /dev/null +++ b/dozer-tutorial/src/main/java/com/baeldung/dozer/Person3.java @@ -0,0 +1,39 @@ +package com.baeldung.dozer; + +public class Person3 { + private String name; + private String dtob; + + public Person3() { + + } + + public Person3(String name, String dtob) { + super(); + this.name = name; + this.dtob = dtob; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDtob() { + return dtob; + } + + public void setDtob(String dtob) { + this.dtob = dtob; + } + + @Override + public String toString() { + return "Person3 [name=" + name + ", dtob=" + dtob + "]"; + } + + +} diff --git a/dozer-tutorial/src/main/java/com/baeldung/dozer/Personne.java b/dozer-tutorial/src/main/java/com/baeldung/dozer/Personne.java new file mode 100644 index 0000000000..f6ff22c96b --- /dev/null +++ b/dozer-tutorial/src/main/java/com/baeldung/dozer/Personne.java @@ -0,0 +1,43 @@ +package com.baeldung.dozer; + +public class Personne { + private String nom; + private String surnom; + private int age; + + public Personne() { + + } + + public Personne(String nom, String surnom, int age) { + super(); + this.nom = nom; + this.surnom = surnom; + this.age = age; + } + + public String getNom() { + return nom; + } + + public void setNom(String nom) { + this.nom = nom; + } + + public String getSurnom() { + return surnom; + } + + public void setSurnom(String surnom) { + this.surnom = surnom; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/dozer-tutorial/src/main/java/com/baeldung/dozer/Personne2.java b/dozer-tutorial/src/main/java/com/baeldung/dozer/Personne2.java new file mode 100644 index 0000000000..1cd3f7cdfd --- /dev/null +++ b/dozer-tutorial/src/main/java/com/baeldung/dozer/Personne2.java @@ -0,0 +1,47 @@ +package com.baeldung.dozer; + +import org.dozer.Mapping; + +public class Personne2 { + private String nom; + private String surnom; + private int age; + + public Personne2() { + + } + + public Personne2(String nom, String surnom, int age) { + super(); + this.nom = nom; + this.surnom = surnom; + this.age = age; + } + + @Mapping("name") + public String getNom() { + return nom; + } + + @Mapping("nickname") + public String getSurnom() { + return surnom; + } + + public void setNom(String nom) { + this.nom = nom; + } + + public void setSurnom(String surnom) { + this.surnom = surnom; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/dozer-tutorial/src/main/java/com/baeldung/dozer/Personne3.java b/dozer-tutorial/src/main/java/com/baeldung/dozer/Personne3.java new file mode 100644 index 0000000000..04af1fe2d1 --- /dev/null +++ b/dozer-tutorial/src/main/java/com/baeldung/dozer/Personne3.java @@ -0,0 +1,38 @@ +package com.baeldung.dozer; + +public class Personne3 { + private String name; + private long dtob; + + public Personne3() { + + } + + public Personne3(String name, long dtob) { + super(); + this.name = name; + this.dtob = dtob; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getDtob() { + return dtob; + } + + public void setDtob(long dtob) { + this.dtob = dtob; + } + + @Override + public String toString() { + return "Personne3 [name=" + name + ", dtob=" + dtob + "]"; + } + +} diff --git a/dozer-tutorial/src/main/java/com/baeldung/dozer/Source.java b/dozer-tutorial/src/main/java/com/baeldung/dozer/Source.java new file mode 100644 index 0000000000..88b3c7a349 --- /dev/null +++ b/dozer-tutorial/src/main/java/com/baeldung/dozer/Source.java @@ -0,0 +1,32 @@ +package com.baeldung.dozer; + +public class Source { + private String name; + private int age; + + public Source() { + } + + public Source(String name, int age) { + super(); + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/dozer-tutorial/src/main/java/com/baeldung/dozer/Source2.java b/dozer-tutorial/src/main/java/com/baeldung/dozer/Source2.java new file mode 100644 index 0000000000..ca7e5baaea --- /dev/null +++ b/dozer-tutorial/src/main/java/com/baeldung/dozer/Source2.java @@ -0,0 +1,38 @@ +package com.baeldung.dozer; + +public class Source2 { + private String id; + private double points; + + public Source2() { + + } + + public Source2(String id, double points) { + super(); + this.id = id; + this.points = points; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public double getPoints() { + return points; + } + + public void setPoints(double points) { + this.points = points; + } + + @Override + public String toString() { + return "Source2 [id=" + id + ", points=" + points + "]"; + } + +} diff --git a/dozer-tutorial/src/test/java/com/baeldung/dozer/DozerTest.java b/dozer-tutorial/src/test/java/com/baeldung/dozer/DozerTest.java new file mode 100644 index 0000000000..ea356d307a --- /dev/null +++ b/dozer-tutorial/src/test/java/com/baeldung/dozer/DozerTest.java @@ -0,0 +1,204 @@ +package com.baeldung.dozer; + +import static org.junit.Assert.*; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import org.dozer.DozerBeanMapper; +import org.dozer.loader.api.BeanMappingBuilder; +import org.junit.Before; +import org.junit.Test; + +public class DozerTest { + DozerBeanMapper mapper = new DozerBeanMapper(); + private final long GMT_DIFFERENCE=46800000; + @Before + public void before() throws Exception { + mapper = new DozerBeanMapper(); + } + + private BeanMappingBuilder builder = new BeanMappingBuilder() { + + @Override + protected void configure() { + mapping(Person.class, Personne.class).fields("name", "nom").fields( + "nickname", "surnom"); + + } + }; + private BeanMappingBuilder builderMinusAge = new BeanMappingBuilder() { + + @Override + protected void configure() { + mapping(Person.class, Personne.class).fields("name", "nom") + .fields("nickname", "surnom").exclude("age"); + + } + }; + + @Test + public void givenApiMapper_whenMaps_thenCorrect() { + Personne frenchAppPerson = new Personne("Sylvester Stallone", "Rambo", + 70); + mapper.addMapping(builder); + Person englishAppPerson = mapper.map(frenchAppPerson, Person.class); + assertEquals(englishAppPerson.getName(), frenchAppPerson.getNom()); + assertEquals(englishAppPerson.getNickname(), + frenchAppPerson.getSurnom()); + assertEquals(englishAppPerson.getAge(), frenchAppPerson.getAge()); + } + + @Test + public void givenApiMapper_whenMapsOnlySpecifiedFields_thenCorrect() { + Person englishAppPerson = new Person("Sylvester Stallone", "Rambo", 70); + mapper.addMapping(builderMinusAge); + Personne frenchAppPerson = mapper.map(englishAppPerson, Personne.class); + assertEquals(frenchAppPerson.getNom(), englishAppPerson.getName()); + assertEquals(frenchAppPerson.getSurnom(), + englishAppPerson.getNickname()); + assertEquals(frenchAppPerson.getAge(), 0); + } + + @Test + public void givenApiMapper_whenMapsBidirectionally_thenCorrect() { + Person englishAppPerson = new Person("Sylvester Stallone", "Rambo", 70); + mapper.addMapping(builder); + Personne frenchAppPerson = mapper.map(englishAppPerson, Personne.class); + assertEquals(frenchAppPerson.getNom(), englishAppPerson.getName()); + assertEquals(frenchAppPerson.getSurnom(), + englishAppPerson.getNickname()); + assertEquals(frenchAppPerson.getAge(), englishAppPerson.getAge()); + } + + @Test + public void givenSourceObjectAndDestClass_whenMapsSameNameFieldsCorrectly_thenCorrect() { + Source source = new Source("Baeldung", 10); + Dest dest = mapper.map(source, Dest.class); + assertEquals(dest.getName(), "Baeldung"); + assertEquals(dest.getAge(), 10); + } + + @Test + public void givenSourceObjectAndDestObject_whenMapsSameNameFieldsCorrectly_thenCorrect() { + Source source = new Source("Baeldung", 10); + Dest dest = new Dest(); + mapper.map(source, dest); + assertEquals(dest.getName(), "Baeldung"); + assertEquals(dest.getAge(), 10); + } + + @Test + public void givenSourceAndDestWithDifferentFieldTypes_whenMapsAndAutoConverts_thenCorrect() { + Source2 source = new Source2("320", 15.2); + Dest2 dest = mapper.map(source, Dest2.class); + assertEquals(dest.getId(), 320); + assertEquals(dest.getPoints(), 15); + } + + @Test + public void givenSrcAndDestWithDifferentFieldNamesWithCustomMapper_whenMaps_thenCorrect() { + List mappingFiles = new ArrayList<>(); + mappingFiles.add("dozer_mapping.xml"); + Personne frenchAppPerson = new Personne("Sylvester Stallone", "Rambo", + 70); + mapper.setMappingFiles(mappingFiles); + Person englishAppPerson = mapper.map(frenchAppPerson, Person.class); + assertEquals(englishAppPerson.getName(), frenchAppPerson.getNom()); + assertEquals(englishAppPerson.getNickname(), + frenchAppPerson.getSurnom()); + assertEquals(englishAppPerson.getAge(), frenchAppPerson.getAge()); + } + + @Test + public void givenSrcAndDestWithDifferentFieldNamesWithCustomMapper_whenMapsBidirectionally_thenCorrect() { + List mappingFiles = new ArrayList<>(); + mappingFiles.add("dozer_mapping.xml"); + Person englishAppPerson = new Person("Dwayne Johnson", "The Rock", 44); + mapper.setMappingFiles(mappingFiles); + Personne frenchAppPerson = mapper.map(englishAppPerson, Personne.class); + assertEquals(frenchAppPerson.getNom(), englishAppPerson.getName()); + assertEquals(frenchAppPerson.getSurnom(), + englishAppPerson.getNickname()); + assertEquals(frenchAppPerson.getAge(), englishAppPerson.getAge()); + } + +// @Test +// public void givenMappingFileOutsideClasspath_whenMaps_thenCorrect() { +// List mappingFiles = new ArrayList<>(); +// mappingFiles.add("file:E:\\dozer_mapping.xml"); +// Person englishAppPerson = new Person("Marshall Bruce Mathers III", +// "Eminem", 43); +// mapper.setMappingFiles(mappingFiles); +// Personne frenchAppPerson = mapper.map(englishAppPerson, Personne.class); +// assertEquals(frenchAppPerson.getNom(), englishAppPerson.getName()); +// assertEquals(frenchAppPerson.getSurnom(), +// englishAppPerson.getNickname()); +// assertEquals(frenchAppPerson.getAge(), englishAppPerson.getAge()); +// } + + @Test + public void givenSrcAndDest_whenMapsOnlySpecifiedFields_thenCorrect() { + List mappingFiles = new ArrayList<>(); + mappingFiles.add("dozer_mapping2.xml"); + Person englishAppPerson = new Person("Shawn Corey Carter", "Jay Z", 46); + mapper.setMappingFiles(mappingFiles); + Personne frenchAppPerson = mapper.map(englishAppPerson, Personne.class); + assertEquals(frenchAppPerson.getNom(), englishAppPerson.getName()); + assertEquals(frenchAppPerson.getSurnom(), + englishAppPerson.getNickname()); + assertEquals(frenchAppPerson.getAge(), 0); + } + + @Test + public void givenAnnotatedSrcFields_whenMapsToRightDestField_thenCorrect() { + Person2 englishAppPerson = new Person2("Jean-Claude Van Damme", "JCVD", + 55); + Personne2 frenchAppPerson = mapper.map(englishAppPerson, + Personne2.class); + assertEquals(frenchAppPerson.getNom(), englishAppPerson.getName()); + assertEquals(frenchAppPerson.getSurnom(), + englishAppPerson.getNickname()); + assertEquals(frenchAppPerson.getAge(), englishAppPerson.getAge()); + } + + @Test + public void givenAnnotatedSrcFields_whenMapsToRightDestFieldBidirectionally_thenCorrect() { + Personne2 frenchAppPerson = new Personne2("Jason Statham", + "transporter", 49); + Person2 englishAppPerson = mapper.map(frenchAppPerson, Person2.class); + assertEquals(englishAppPerson.getName(), frenchAppPerson.getNom()); + assertEquals(englishAppPerson.getNickname(), + frenchAppPerson.getSurnom()); + assertEquals(englishAppPerson.getAge(), frenchAppPerson.getAge()); + } + + @Test + public void givenSrcAndDestWithDifferentFieldTypes_whenAbleToCustomConvert_thenCorrect() { + String dateTime = "2007-06-26T21:22:39Z"; + long timestamp = new Long("1182882159000"); + Person3 person = new Person3("Rich", dateTime); + mapper.setMappingFiles(Arrays + .asList(new String[] { "dozer_custom_convertor.xml" })); + Personne3 person0 = mapper.map(person, Personne3.class); + long timestampToTest=person0.getDtob(); + assertTrue(timestampToTest==timestamp||timestampToTest>=timestamp-GMT_DIFFERENCE||timestampToTest<=timestamp+GMT_DIFFERENCE); + } + + @Test + public void givenSrcAndDestWithDifferentFieldTypes_whenAbleToCustomConvertBidirectionally_thenCorrect() { + String dateTime = "2007-06-26T21:22:39Z"; + long timestamp = new Long("1182882159000"); + Personne3 person = new Personne3("Rich", timestamp); + mapper.setMappingFiles(Arrays + .asList(new String[] { "dozer_custom_convertor.xml" })); + Person3 person0 = mapper.map(person, Person3.class); + String timestampTest=person0.getDtob(); + assertTrue(timestampTest.charAt(10)=='T'&×tampTest.charAt(19)=='Z'); + } +} diff --git a/dozer-tutorial/src/test/resources/dozer_custom_convertor.xml b/dozer-tutorial/src/test/resources/dozer_custom_convertor.xml new file mode 100644 index 0000000000..0cbe5a7918 --- /dev/null +++ b/dozer-tutorial/src/test/resources/dozer_custom_convertor.xml @@ -0,0 +1,14 @@ + + + + + + com.baeldung.dozer.Personne3 + com.baeldung.dozer.Person3 + + + + + \ No newline at end of file diff --git a/dozer-tutorial/src/test/resources/dozer_mapping.xml b/dozer-tutorial/src/test/resources/dozer_mapping.xml new file mode 100644 index 0000000000..13f31db11a --- /dev/null +++ b/dozer-tutorial/src/test/resources/dozer_mapping.xml @@ -0,0 +1,17 @@ + + + + com.baeldung.dozer.Personne + com.baeldung.dozer.Person + + nom + name + + + surnom + nickname + + + \ No newline at end of file diff --git a/dozer-tutorial/src/test/resources/dozer_mapping2.xml b/dozer-tutorial/src/test/resources/dozer_mapping2.xml new file mode 100644 index 0000000000..63411568b6 --- /dev/null +++ b/dozer-tutorial/src/test/resources/dozer_mapping2.xml @@ -0,0 +1,17 @@ + + + + com.baeldung.dozer.Personne + com.baeldung.dozer.Person + + nom + name + + + surnom + nickname + + + \ No newline at end of file diff --git a/hystrix/src/main/java/com/baeldung/hystrix/RemoteServiceSimulator.java b/hystrix/src/main/java/com/baeldung/hystrix/RemoteServiceSimulator.java new file mode 100644 index 0000000000..3efd579d84 --- /dev/null +++ b/hystrix/src/main/java/com/baeldung/hystrix/RemoteServiceSimulator.java @@ -0,0 +1,15 @@ +package com.baeldung.hystrix; + + +public class RemoteServiceSimulator { + + public String checkSomething(final long timeout) throws InterruptedException { + + System.out.print(String.format("Waiting %sms. ", timeout)); + + // to simulate a real world delay in processing. + Thread.sleep(timeout); + + return "Done waiting."; + } +} diff --git a/immutables/pom.xml b/immutables/pom.xml new file mode 100644 index 0000000000..2b4aba59b1 --- /dev/null +++ b/immutables/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + com.baeldung + immutables + 1.0.0-SNAPSHOT + + + + org.immutables + value + 2.2.10 + + + junit + junit + 4.12 + test + + + org.assertj + assertj-core + 3.5.2 + test + + + org.mutabilitydetector + MutabilityDetector + 0.9.5 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/immutables/src/main/java/com/baeldung/immutable/Address.java b/immutables/src/main/java/com/baeldung/immutable/Address.java new file mode 100644 index 0000000000..93474dc043 --- /dev/null +++ b/immutables/src/main/java/com/baeldung/immutable/Address.java @@ -0,0 +1,9 @@ +package com.baeldung.immutable; + +import org.immutables.value.Value; + +@Value.Immutable +public interface Address { + String getStreetName(); + Integer getNumber(); +} diff --git a/immutables/src/main/java/com/baeldung/immutable/Person.java b/immutables/src/main/java/com/baeldung/immutable/Person.java new file mode 100644 index 0000000000..466daf42c2 --- /dev/null +++ b/immutables/src/main/java/com/baeldung/immutable/Person.java @@ -0,0 +1,9 @@ +package com.baeldung.immutable; + +import org.immutables.value.Value; + +@Value.Immutable +public abstract class Person { + abstract String getName(); + abstract Integer getAge(); +} diff --git a/immutables/src/main/java/com/baeldung/immutable/auxiliary/Person.java b/immutables/src/main/java/com/baeldung/immutable/auxiliary/Person.java new file mode 100644 index 0000000000..78fe28c50c --- /dev/null +++ b/immutables/src/main/java/com/baeldung/immutable/auxiliary/Person.java @@ -0,0 +1,13 @@ +package com.baeldung.immutable.auxiliary; + + +import org.immutables.value.Value; + +@Value.Immutable +public abstract class Person { + abstract String getName(); + abstract Integer getAge(); + + @Value.Auxiliary + abstract String getAuxiliaryField(); +} \ No newline at end of file diff --git a/immutables/src/main/java/com/baeldung/immutable/default_/Person.java b/immutables/src/main/java/com/baeldung/immutable/default_/Person.java new file mode 100644 index 0000000000..bc48f11a38 --- /dev/null +++ b/immutables/src/main/java/com/baeldung/immutable/default_/Person.java @@ -0,0 +1,14 @@ +package com.baeldung.immutable.default_; + +import org.immutables.value.Value; + +@Value.Immutable(prehash = true) +public abstract class Person { + + abstract String getName(); + + @Value.Default + Integer getAge() { + return 42; + } +} diff --git a/immutables/src/main/java/com/baeldung/immutable/parameter/Person.java b/immutables/src/main/java/com/baeldung/immutable/parameter/Person.java new file mode 100644 index 0000000000..4e8218f99c --- /dev/null +++ b/immutables/src/main/java/com/baeldung/immutable/parameter/Person.java @@ -0,0 +1,14 @@ +package com.baeldung.immutable.parameter; + + +import org.immutables.value.Value; + +@Value.Immutable +public abstract class Person { + + @Value.Parameter + abstract String getName(); + + @Value.Parameter + abstract Integer getAge(); +} \ No newline at end of file diff --git a/immutables/src/main/java/com/baeldung/immutable/prehash/Person.java b/immutables/src/main/java/com/baeldung/immutable/prehash/Person.java new file mode 100644 index 0000000000..5e5dd4d9e9 --- /dev/null +++ b/immutables/src/main/java/com/baeldung/immutable/prehash/Person.java @@ -0,0 +1,9 @@ +package com.baeldung.immutable.prehash; + +import org.immutables.value.Value; + +@Value.Immutable(prehash = true) +public abstract class Person { + abstract String getName(); + abstract Integer getAge(); +} diff --git a/immutables/src/test/java/com/baeldung/immutable/ImmutablePersonTest.java b/immutables/src/test/java/com/baeldung/immutable/ImmutablePersonTest.java new file mode 100644 index 0000000000..bf075569db --- /dev/null +++ b/immutables/src/test/java/com/baeldung/immutable/ImmutablePersonTest.java @@ -0,0 +1,27 @@ +package com.baeldung.immutable; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mutabilitydetector.unittesting.MutabilityAssert.assertImmutable; + +public class ImmutablePersonTest { + + @Test + public void whenModifying_shouldCreateNewInstance() throws Exception { + final ImmutablePerson john = ImmutablePerson.builder() + .age(42) + .name("John") + .build(); + + final ImmutablePerson john43 = john.withAge(43); + + assertThat(john) + .isNotSameAs(john43); + + assertThat(john.getAge()) + .isEqualTo(42); + + assertImmutable(ImmutablePerson.class); + } +} \ No newline at end of file diff --git a/immutables/src/test/java/com/baeldung/immutable/auxiliary/ImmutablePersonAuxiliaryTest.java b/immutables/src/test/java/com/baeldung/immutable/auxiliary/ImmutablePersonAuxiliaryTest.java new file mode 100644 index 0000000000..83f9e51ed5 --- /dev/null +++ b/immutables/src/test/java/com/baeldung/immutable/auxiliary/ImmutablePersonAuxiliaryTest.java @@ -0,0 +1,33 @@ +package com.baeldung.immutable.auxiliary; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ImmutablePersonAuxiliaryTest { + + @Test + public void whenComparing_shouldIgnore() throws Exception { + final ImmutablePerson john1 = ImmutablePerson.builder() + .name("John") + .age(42) + .auxiliaryField("Value1") + .build(); + + final ImmutablePerson john2 = ImmutablePerson.builder() + .name("John") + .age(42) + .auxiliaryField("Value2") + .build(); + + + assertThat(john1.equals(john2)) + .isTrue(); + + assertThat(john1.toString()) + .isEqualTo(john2.toString()); + + assertThat(john1.hashCode()) + .isEqualTo(john2.hashCode()); + } +} \ No newline at end of file diff --git a/immutables/src/test/java/com/baeldung/immutable/default_/ImmutablePersonDefaultTest.java b/immutables/src/test/java/com/baeldung/immutable/default_/ImmutablePersonDefaultTest.java new file mode 100644 index 0000000000..5cf4ac0cf7 --- /dev/null +++ b/immutables/src/test/java/com/baeldung/immutable/default_/ImmutablePersonDefaultTest.java @@ -0,0 +1,17 @@ +package com.baeldung.immutable.default_; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ImmutablePersonDefaultTest { + + @Test + public void whenInstantiating_shouldUseDefaultValue() throws Exception { + + final ImmutablePerson john = ImmutablePerson.builder().name("John").build(); + + assertThat(john.getAge()).isEqualTo(42); + + } +} \ No newline at end of file diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java b/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java index 88ee1cd673..a3d0b377c6 100644 --- a/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java +++ b/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java @@ -7,18 +7,26 @@ import org.slf4j.LoggerFactory; import com.baeldung.jackson.objectmapper.dto.Car; import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -public class CustomCarDeserializer extends JsonDeserializer { +public class CustomCarDeserializer extends StdDeserializer { + + private static final long serialVersionUID = -5918629454846356161L; private final Logger Logger = LoggerFactory.getLogger(getClass()); public CustomCarDeserializer() { + this(null); } + public CustomCarDeserializer(final Class vc) { + super(vc); + } + + + @Override public Car deserialize(final JsonParser parser, final DeserializationContext deserializer) throws IOException { final Car car = new Car(); diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java b/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java index 08c7184d29..37bae829b7 100644 --- a/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java +++ b/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java @@ -1,16 +1,25 @@ package com.baeldung.jackson.objectmapper; +import java.io.IOException; + import com.baeldung.jackson.objectmapper.dto.Car; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; -import java.io.IOException; - -public class CustomCarSerializer extends JsonSerializer +public class CustomCarSerializer extends StdSerializer { - public CustomCarSerializer() { } + + private static final long serialVersionUID = 1396140685442227917L; + + public CustomCarSerializer() { + this(null); + } + + public CustomCarSerializer(final Class t) { + super(t); + } @Override public void serialize(final Car car, final JsonGenerator jsonGenerator, final SerializerProvider serializer) throws IOException, JsonProcessingException diff --git a/mocks/jmockit/README.md b/mocks/jmockit/README.md index d04a07fdc5..db78b2a3ac 100644 --- a/mocks/jmockit/README.md +++ b/mocks/jmockit/README.md @@ -6,3 +6,4 @@ ### Relevant Articles: - [JMockit 101](http://www.baeldung.com/jmockit-101) - [A Guide to JMockit Expectations](http://www.baeldung.com/jmockit-expectations) +- [JMockit Advanced Topics](http://www.baeldung.com/jmockit-advanced-topics) diff --git a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java new file mode 100644 index 0000000000..4d25f466a6 --- /dev/null +++ b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java @@ -0,0 +1,20 @@ +package org.baeldung.mocks.jmockit; + +public class AdvancedCollaborator { + int i; + private int privateField = 5; + public AdvancedCollaborator(){} + public AdvancedCollaborator(String string) throws Exception{ + i = string.length(); + } + public String methodThatCallsPrivateMethod(int i){ + return privateMethod() + i; + } + public int methodThatReturnsThePrivateField(){ + return privateField; + } + private String privateMethod(){ + return "default:"; + } + class InnerAdvancedCollaborator{} +} diff --git a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/ReusingTest.java b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/ReusingTest.java new file mode 100644 index 0000000000..729cb30cd2 --- /dev/null +++ b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/ReusingTest.java @@ -0,0 +1,57 @@ +package org.baeldung.mocks.jmockit; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import mockit.Expectations; +import mockit.Injectable; +import mockit.Mocked; +import mockit.Tested; +import mockit.Verifications; +import mockit.integration.junit4.JMockit; + +@RunWith(JMockit.class) +public class ReusingTest { + + @Injectable + private Collaborator collaborator; + + @Mocked + private Model model; + + @Tested + private Performer performer; + + @Before + public void setup(){ + new Expectations(){{ + model.getInfo(); result = "foo"; minTimes = 0; + collaborator.collaborate("foo"); result = true; minTimes = 0; + }}; + } + + @Test + public void testWithSetup() { + performer.perform(model); + verifyTrueCalls(1); + } + + protected void verifyTrueCalls(int calls){ + new Verifications(){{ + collaborator.receive(true); times = calls; + }}; + } + + final class TrueCallsVerification extends Verifications{ + public TrueCallsVerification(int calls){ + collaborator.receive(true); times = calls; + } + } + + @Test + public void testWithFinalClass() { + performer.perform(model); + new TrueCallsVerification(1); + } +} diff --git a/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorTest.java b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorTest.java new file mode 100644 index 0000000000..aaabe44f66 --- /dev/null +++ b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorTest.java @@ -0,0 +1,110 @@ +package org.baeldung.mocks.jmockit; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.ArrayList; +import java.util.List; + +import org.baeldung.mocks.jmockit.AdvancedCollaborator.InnerAdvancedCollaborator; +import org.junit.Test; +import org.junit.runner.RunWith; + +import mockit.Deencapsulation; +import mockit.Expectations; +import mockit.Invocation; +import mockit.Mock; +import mockit.MockUp; +import mockit.Mocked; +import mockit.Tested; +import mockit.integration.junit4.JMockit; + +@RunWith(JMockit.class) +public class AdvancedCollaboratorTest & Comparable>> { + + @Tested + private AdvancedCollaborator mock; + + @Mocked + private MultiMock multiMock; + + @Test + public void testToMockUpPrivateMethod() { + new MockUp() { + @Mock + private String privateMethod() { + return "mocked: "; + } + }; + String res = mock.methodThatCallsPrivateMethod(1); + assertEquals("mocked: 1", res); + } + + @Test + public void testToMockUpDifficultConstructor() throws Exception { + new MockUp() { + @Mock + public void $init(Invocation invocation, String string) { + ((AdvancedCollaborator) invocation.getInvokedInstance()).i = 1; + } + }; + AdvancedCollaborator coll = new AdvancedCollaborator(null); + assertEquals(1, coll.i); + } + + @Test + public void testToCallPrivateMethodsDirectly() { + Object value = Deencapsulation.invoke(mock, "privateMethod"); + assertEquals("default:", value); + } + + @Test + public void testToSetPrivateFieldDirectly() { + Deencapsulation.setField(mock, "privateField", 10); + assertEquals(10, mock.methodThatReturnsThePrivateField()); + } + + @Test + public void testToGetPrivateFieldDirectly() { + int value = Deencapsulation.getField(mock, "privateField"); + assertEquals(5, value); + } + + @Test + public void testToCreateNewInstanceDirectly() { + AdvancedCollaborator coll = Deencapsulation.newInstance(AdvancedCollaborator.class, "foo"); + assertEquals(3, coll.i); + } + + @Test + public void testToCreateNewInnerClassInstanceDirectly() { + InnerAdvancedCollaborator innerCollaborator = Deencapsulation.newInnerInstance(InnerAdvancedCollaborator.class, mock); + assertNotNull(innerCollaborator); + } + + @Test + @SuppressWarnings("unchecked") + public void testMultipleInterfacesWholeTest() { + new Expectations() { + { + multiMock.get(5); result = "foo"; + multiMock.compareTo((List) any); result = 0; + } + }; + assertEquals("foo", multiMock.get(5)); + assertEquals(0, multiMock.compareTo(new ArrayList<>())); + } + + @Test + @SuppressWarnings("unchecked") + public & Comparable>> void testMultipleInterfacesOneMethod(@Mocked M mock) { + new Expectations() { + { + mock.get(5); result = "foo"; + mock.compareTo((List) any); + result = 0; } + }; + assertEquals("foo", mock.get(5)); + assertEquals(0, mock.compareTo(new ArrayList<>())); + } +} diff --git a/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingTest.java b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingTest.java new file mode 100644 index 0000000000..729cb30cd2 --- /dev/null +++ b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingTest.java @@ -0,0 +1,57 @@ +package org.baeldung.mocks.jmockit; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import mockit.Expectations; +import mockit.Injectable; +import mockit.Mocked; +import mockit.Tested; +import mockit.Verifications; +import mockit.integration.junit4.JMockit; + +@RunWith(JMockit.class) +public class ReusingTest { + + @Injectable + private Collaborator collaborator; + + @Mocked + private Model model; + + @Tested + private Performer performer; + + @Before + public void setup(){ + new Expectations(){{ + model.getInfo(); result = "foo"; minTimes = 0; + collaborator.collaborate("foo"); result = true; minTimes = 0; + }}; + } + + @Test + public void testWithSetup() { + performer.perform(model); + verifyTrueCalls(1); + } + + protected void verifyTrueCalls(int calls){ + new Verifications(){{ + collaborator.receive(true); times = calls; + }}; + } + + final class TrueCallsVerification extends Verifications{ + public TrueCallsVerification(int calls){ + collaborator.receive(true); times = calls; + } + } + + @Test + public void testWithFinalClass() { + performer.perform(model); + new TrueCallsVerification(1); + } +} diff --git a/pom.xml b/pom.xml index 074f330bcf..419916de86 100644 --- a/pom.xml +++ b/pom.xml @@ -31,6 +31,7 @@ guava19 handling-spring-static-resources httpclient + immutables jackson javaxval jjwt @@ -55,7 +56,7 @@ spring-autowire spring-batch spring-boot - spring-controller + spring-cucumber spring-data-cassandra spring-data-couchbase-2 spring-data-couchbase-2b diff --git a/spring-all/.settings/.jsdtscope b/spring-all/.settings/.jsdtscope deleted file mode 100644 index b46b9207a8..0000000000 --- a/spring-all/.settings/.jsdtscope +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/spring-all/.settings/org.eclipse.jdt.core.prefs b/spring-all/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index b126d6476b..0000000000 --- a/spring-all/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,95 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=error -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=error -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/spring-all/.settings/org.eclipse.jdt.ui.prefs b/spring-all/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100644 index 471e9b0d81..0000000000 --- a/spring-all/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,55 +0,0 @@ -#Sat Jan 21 23:04:06 EET 2012 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=true -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=true -sp_cleanup.correct_indentation=true -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=true -sp_cleanup.make_local_variable_final=true -sp_cleanup.make_parameters_final=true -sp_cleanup.make_private_fields_final=false -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=true -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=false -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=true -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=true -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=true -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/spring-all/.settings/org.eclipse.m2e.core.prefs b/spring-all/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f1cb..0000000000 --- a/spring-all/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/spring-all/.settings/org.eclipse.m2e.wtp.prefs b/spring-all/.settings/org.eclipse.m2e.wtp.prefs deleted file mode 100644 index ef86089622..0000000000 --- a/spring-all/.settings/org.eclipse.m2e.wtp.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.m2e.wtp.enabledProjectSpecificPrefs=false diff --git a/spring-all/.settings/org.eclipse.wst.common.component b/spring-all/.settings/org.eclipse.wst.common.component deleted file mode 100644 index 847c6ff698..0000000000 --- a/spring-all/.settings/org.eclipse.wst.common.component +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/spring-all/.settings/org.eclipse.wst.common.project.facet.core.xml b/spring-all/.settings/org.eclipse.wst.common.project.facet.core.xml deleted file mode 100644 index 991897a4ac..0000000000 --- a/spring-all/.settings/org.eclipse.wst.common.project.facet.core.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/spring-all/.settings/org.eclipse.wst.jsdt.ui.superType.container b/spring-all/.settings/org.eclipse.wst.jsdt.ui.superType.container deleted file mode 100644 index 3bd5d0a480..0000000000 --- a/spring-all/.settings/org.eclipse.wst.jsdt.ui.superType.container +++ /dev/null @@ -1 +0,0 @@ -org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/spring-all/.settings/org.eclipse.wst.jsdt.ui.superType.name b/spring-all/.settings/org.eclipse.wst.jsdt.ui.superType.name deleted file mode 100644 index 05bd71b6ec..0000000000 --- a/spring-all/.settings/org.eclipse.wst.jsdt.ui.superType.name +++ /dev/null @@ -1 +0,0 @@ -Window \ No newline at end of file diff --git a/spring-all/.settings/org.eclipse.wst.validation.prefs b/spring-all/.settings/org.eclipse.wst.validation.prefs deleted file mode 100644 index 0d0aee4f72..0000000000 --- a/spring-all/.settings/org.eclipse.wst.validation.prefs +++ /dev/null @@ -1,15 +0,0 @@ -DELEGATES_PREFERENCE=delegateValidatorList -USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator; -USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator; -USER_PREFERENCE=overrideGlobalPreferencestruedisableAllValidationfalseversion1.2.402.v201212031633 -disabled=06target -eclipse.preferences.version=1 -override=true -suspend=false -vals/org.eclipse.jst.jsf.ui.JSFAppConfigValidator/global=FF01 -vals/org.eclipse.jst.jsp.core.JSPBatchValidator/global=FF01 -vals/org.eclipse.jst.jsp.core.JSPContentValidator/global=FF01 -vals/org.eclipse.jst.jsp.core.TLDValidator/global=FF01 -vals/org.eclipse.wst.dtd.core.dtdDTDValidator/global=FF01 -vals/org.eclipse.wst.jsdt.web.core.JsBatchValidator/global=TF02 -vf.version=3 diff --git a/spring-all/.settings/org.eclipse.wst.ws.service.policy.prefs b/spring-all/.settings/org.eclipse.wst.ws.service.policy.prefs deleted file mode 100644 index 9cfcabe16f..0000000000 --- a/spring-all/.settings/org.eclipse.wst.ws.service.policy.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.wst.ws.service.policy.projectEnabled=false diff --git a/spring-all/pom.xml b/spring-all/pom.xml index 5f14d32121..b7a8fcc79e 100644 --- a/spring-all/pom.xml +++ b/spring-all/pom.xml @@ -14,6 +14,10 @@ + + com.fasterxml.jackson.core + jackson-databind + @@ -41,11 +45,6 @@ spring-aspects - - org.springframework - spring-orm - - @@ -88,6 +87,14 @@ runtime + + + + com.typesafe.akka + akka-actor_2.11 + 2.4.8 + + diff --git a/spring-all/src/main/java/org/baeldung/akka/AppConfiguration.java b/spring-all/src/main/java/org/baeldung/akka/AppConfiguration.java new file mode 100644 index 0000000000..9211ae0fdb --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/akka/AppConfiguration.java @@ -0,0 +1,26 @@ +package org.baeldung.akka; + +import akka.actor.ActorSystem; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import static org.baeldung.akka.SpringExtension.SPRING_EXTENSION_PROVIDER; + +@Configuration +@ComponentScan +public class AppConfiguration { + + @Autowired + private ApplicationContext applicationContext; + + @Bean + public ActorSystem actorSystem() { + ActorSystem system = ActorSystem.create("akka-spring-demo"); + SPRING_EXTENSION_PROVIDER.get(system).initialize(applicationContext); + return system; + } + +} diff --git a/spring-all/src/main/java/org/baeldung/akka/GreetingActor.java b/spring-all/src/main/java/org/baeldung/akka/GreetingActor.java new file mode 100644 index 0000000000..1a9386c769 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/akka/GreetingActor.java @@ -0,0 +1,43 @@ +package org.baeldung.akka; + +import akka.actor.UntypedActor; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import static org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_PROTOTYPE; + +@Component +@Scope(SCOPE_PROTOTYPE) +public class GreetingActor extends UntypedActor { + + private GreetingService greetingService; + + public GreetingActor(GreetingService greetingService) { + this.greetingService = greetingService; + } + + @Override + public void onReceive(Object message) throws Throwable { + if (message instanceof Greet) { + String name = ((Greet) message).getName(); + getSender().tell(greetingService.greet(name), getSelf()); + } else { + unhandled(message); + } + } + + public static class Greet { + + private String name; + + public Greet(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + } + +} diff --git a/spring-all/src/main/java/org/baeldung/akka/GreetingService.java b/spring-all/src/main/java/org/baeldung/akka/GreetingService.java new file mode 100644 index 0000000000..801921887d --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/akka/GreetingService.java @@ -0,0 +1,12 @@ +package org.baeldung.akka; + +import org.springframework.stereotype.Component; + +@Component +public class GreetingService { + + public String greet(String name) { + return "Hello, " + name; + } + +} diff --git a/spring-all/src/main/java/org/baeldung/akka/SpringActorProducer.java b/spring-all/src/main/java/org/baeldung/akka/SpringActorProducer.java new file mode 100644 index 0000000000..20813ab60a --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/akka/SpringActorProducer.java @@ -0,0 +1,28 @@ +package org.baeldung.akka; + +import akka.actor.Actor; +import akka.actor.IndirectActorProducer; +import org.springframework.context.ApplicationContext; + +public class SpringActorProducer implements IndirectActorProducer { + + private ApplicationContext applicationContext; + + private String beanActorName; + + public SpringActorProducer(ApplicationContext applicationContext, String beanActorName) { + this.applicationContext = applicationContext; + this.beanActorName = beanActorName; + } + + @Override + public Actor produce() { + return (Actor) applicationContext.getBean(beanActorName); + } + + @Override + public Class actorClass() { + return (Class) applicationContext.getType(beanActorName); + } + +} diff --git a/spring-all/src/main/java/org/baeldung/akka/SpringExtension.java b/spring-all/src/main/java/org/baeldung/akka/SpringExtension.java new file mode 100644 index 0000000000..624e289812 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/akka/SpringExtension.java @@ -0,0 +1,33 @@ +package org.baeldung.akka; + +import akka.actor.AbstractExtensionId; +import akka.actor.ExtendedActorSystem; +import akka.actor.Extension; +import akka.actor.Props; +import org.springframework.context.ApplicationContext; + +public class SpringExtension extends AbstractExtensionId { + + public static final SpringExtension SPRING_EXTENSION_PROVIDER = new SpringExtension(); + + @Override + public SpringExt createExtension(ExtendedActorSystem system) { + return new SpringExt(); + } + + public static class SpringExt implements Extension { + + private volatile ApplicationContext applicationContext; + + public void initialize(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + public Props props(String actorBeanName) { + return Props.create(SpringActorProducer.class, applicationContext, actorBeanName); + } + + } + + +} diff --git a/spring-controller/src/main/java/com/baeldung/controller/RestAnnotatedController.java b/spring-all/src/main/java/org/baeldung/controller/controller/RestAnnotatedController.java similarity index 84% rename from spring-controller/src/main/java/com/baeldung/controller/RestAnnotatedController.java rename to spring-all/src/main/java/org/baeldung/controller/controller/RestAnnotatedController.java index 01c9ed4122..48981fd012 100644 --- a/spring-controller/src/main/java/com/baeldung/controller/RestAnnotatedController.java +++ b/spring-all/src/main/java/org/baeldung/controller/controller/RestAnnotatedController.java @@ -1,6 +1,6 @@ -package com.baeldung.controller; +package org.baeldung.controller.controller; -import com.baeldung.student.Student; +import org.baeldung.controller.student.Student; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; diff --git a/spring-controller/src/main/java/com/baeldung/controller/RestController.java b/spring-all/src/main/java/org/baeldung/controller/controller/RestController.java similarity index 84% rename from spring-controller/src/main/java/com/baeldung/controller/RestController.java rename to spring-all/src/main/java/org/baeldung/controller/controller/RestController.java index 1281eeee57..95903bcc40 100644 --- a/spring-controller/src/main/java/com/baeldung/controller/RestController.java +++ b/spring-all/src/main/java/org/baeldung/controller/controller/RestController.java @@ -1,6 +1,6 @@ -package com.baeldung.controller; +package org.baeldung.controller.controller; -import com.baeldung.student.Student; +import org.baeldung.controller.student.Student; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; diff --git a/spring-controller/src/main/java/com/baeldung/controller/TestController.java b/spring-all/src/main/java/org/baeldung/controller/controller/TestController.java similarity index 92% rename from spring-controller/src/main/java/com/baeldung/controller/TestController.java rename to spring-all/src/main/java/org/baeldung/controller/controller/TestController.java index 7397e7a2d3..12ae4e0ab1 100644 --- a/spring-controller/src/main/java/com/baeldung/controller/TestController.java +++ b/spring-all/src/main/java/org/baeldung/controller/controller/TestController.java @@ -2,7 +2,7 @@ /** * @author Prashant Dutta */ -package com.baeldung.controller; +package org.baeldung.controller.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; diff --git a/spring-controller/src/main/java/com/baeldung/student/Student.java b/spring-all/src/main/java/org/baeldung/controller/student/Student.java similarity index 90% rename from spring-controller/src/main/java/com/baeldung/student/Student.java rename to spring-all/src/main/java/org/baeldung/controller/student/Student.java index ca38360928..ee706d7028 100644 --- a/spring-controller/src/main/java/com/baeldung/student/Student.java +++ b/spring-all/src/main/java/org/baeldung/controller/student/Student.java @@ -1,4 +1,4 @@ -package com.baeldung.student; +package org.baeldung.controller.student; public class Student { private String name; diff --git a/spring-controller/src/main/resources/test-mvc.xml b/spring-all/src/main/resources/test-mvc.xml similarity index 92% rename from spring-controller/src/main/resources/test-mvc.xml rename to spring-all/src/main/resources/test-mvc.xml index 858c1b4fe5..15f950ed4f 100644 --- a/spring-controller/src/main/resources/test-mvc.xml +++ b/spring-all/src/main/resources/test-mvc.xml @@ -10,7 +10,7 @@ http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> - + diff --git a/spring-controller/src/main/webapp/WEB-INF/web.xml b/spring-all/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from spring-controller/src/main/webapp/WEB-INF/web.xml rename to spring-all/src/main/webapp/WEB-INF/web.xml diff --git a/spring-controller/src/main/webapp/WEB-INF/welcome.jsp b/spring-all/src/main/webapp/WEB-INF/welcome.jsp similarity index 100% rename from spring-controller/src/main/webapp/WEB-INF/welcome.jsp rename to spring-all/src/main/webapp/WEB-INF/welcome.jsp diff --git a/spring-all/src/test/java/org/baeldung/akka/SpringAkkaTest.java b/spring-all/src/test/java/org/baeldung/akka/SpringAkkaTest.java new file mode 100644 index 0000000000..6162b02307 --- /dev/null +++ b/spring-all/src/test/java/org/baeldung/akka/SpringAkkaTest.java @@ -0,0 +1,48 @@ +package org.baeldung.akka; + +import java.util.concurrent.TimeUnit; + +import akka.actor.ActorRef; +import akka.actor.ActorSystem; +import akka.util.Timeout; +import org.baeldung.akka.GreetingActor.Greet; +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; +import scala.concurrent.Await; +import scala.concurrent.Future; +import scala.concurrent.duration.FiniteDuration; + +import static akka.pattern.Patterns.ask; +import static org.baeldung.akka.SpringExtension.SPRING_EXTENSION_PROVIDER; + +@ContextConfiguration(classes = AppConfiguration.class) +public class SpringAkkaTest extends AbstractJUnit4SpringContextTests { + + @Autowired + private ActorSystem system; + + @Test + public void whenCallingGreetingActor_thenActorGreetsTheCaller() throws Exception { + ActorRef greeter = system.actorOf( + SPRING_EXTENSION_PROVIDER.get(system) + .props("greetingActor"), "greeter"); + + FiniteDuration duration = FiniteDuration.create(1, TimeUnit.SECONDS); + Timeout timeout = Timeout.durationToTimeout(duration); + + Future result = ask(greeter, new Greet("John"), timeout); + + Assert.assertEquals("Hello, John", Await.result(result, duration)); + } + + @After + public void tearDown() { + system.shutdown(); + system.awaitTermination(); + } + +} diff --git a/spring-controller/src/test/java/com/baeldung/test/ControllerTest.java b/spring-all/src/test/java/org/baeldung/controller/ControllerTest.java similarity index 96% rename from spring-controller/src/test/java/com/baeldung/test/ControllerTest.java rename to spring-all/src/test/java/org/baeldung/controller/ControllerTest.java index 8375002213..f5e41cd5a2 100644 --- a/spring-controller/src/test/java/com/baeldung/test/ControllerTest.java +++ b/spring-all/src/test/java/org/baeldung/controller/ControllerTest.java @@ -1,4 +1,4 @@ -package com.baeldung.test; +package org.baeldung.controller; import org.junit.Assert; import org.junit.Before; @@ -14,7 +14,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.ModelAndView; -import com.baeldung.student.Student; +import org.baeldung.controller.student.Student; import com.fasterxml.jackson.databind.ObjectMapper; @RunWith(SpringJUnit4ClassRunner.class) diff --git a/spring-controller/pom.xml b/spring-controller/pom.xml deleted file mode 100644 index d9fd79c095..0000000000 --- a/spring-controller/pom.xml +++ /dev/null @@ -1,56 +0,0 @@ - - 4.0.0 - test - spring-controller - 0.0.1-SNAPSHOT - war - - - - org.springframework - spring-webmvc - 4.3.0.RELEASE - - - - javax.servlet - javax.servlet-api - 3.0.1 - compile - - - com.fasterxml.jackson.core - jackson-databind - 2.6.3 - - - com.fasterxml.jackson.core - jackson-annotations - 2.6.3 - - - com.fasterxml.jackson.core - jackson-core - 2.6.3 - - - org.springframework - spring-web - 4.3.0.RELEASE - - - - junit - junit - 4.12 - test - - - org.springframework - spring-test - 4.2.6.RELEASE - - - - - \ No newline at end of file diff --git a/spring-cucumber/pom.xml b/spring-cucumber/pom.xml new file mode 100644 index 0000000000..f3b9c983f0 --- /dev/null +++ b/spring-cucumber/pom.xml @@ -0,0 +1,89 @@ + + + 4.0.0 + + com.baeldung + spring-cucumber + 0.0.1-SNAPSHOT + jar + + spring-cucumber + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.3.5.RELEASE + + + + + UTF-8 + 1.8 + 1.2.4 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + info.cukes + cucumber-core + ${cucumber.java.version} + test + + + + info.cukes + cucumber-java + ${cucumber.java.version} + test + + + + info.cukes + cucumber-junit + ${cucumber.java.version} + test + + + + info.cukes + cucumber-spring + ${cucumber.java.version} + test + + + + + org.apache.commons + commons-io + 1.3.2 + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-cucumber/src/main/java/com/baeldung/BaeldungController.java b/spring-cucumber/src/main/java/com/baeldung/BaeldungController.java new file mode 100644 index 0000000000..0bb249b814 --- /dev/null +++ b/spring-cucumber/src/main/java/com/baeldung/BaeldungController.java @@ -0,0 +1,22 @@ +package com.baeldung; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class BaeldungController { + + @RequestMapping(method={RequestMethod.GET},value={"/hello"}) + public String sayHello(HttpServletResponse response){ + return "hello"; + } + + @RequestMapping(method={RequestMethod.POST},value={"/baeldung"}) + public String sayHelloPost(HttpServletResponse response){ + return "hello"; + } + +} diff --git a/spring-cucumber/src/main/java/com/baeldung/SpringDemoApplication.java b/spring-cucumber/src/main/java/com/baeldung/SpringDemoApplication.java new file mode 100644 index 0000000000..d490b23aa2 --- /dev/null +++ b/spring-cucumber/src/main/java/com/baeldung/SpringDemoApplication.java @@ -0,0 +1,19 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.context.web.SpringBootServletInitializer; + +@SpringBootApplication +public class SpringDemoApplication extends SpringBootServletInitializer{ + + public static void main(String[] args) { + SpringApplication.run(SpringDemoApplication.class, args); + } + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application){ + return application.sources(SpringDemoApplication.class); + } +} diff --git a/spring-cucumber/src/main/java/com/baeldung/VersionController.java b/spring-cucumber/src/main/java/com/baeldung/VersionController.java new file mode 100644 index 0000000000..7c72a78a05 --- /dev/null +++ b/spring-cucumber/src/main/java/com/baeldung/VersionController.java @@ -0,0 +1,14 @@ +package com.baeldung; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class VersionController { + + @RequestMapping(method={RequestMethod.GET},value={"/version"}) + public String getVersion(){ + return "1.0"; + } +} diff --git a/spring-cucumber/src/main/resources/application.properties b/spring-cucumber/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-cucumber/src/test/java/com/baeldung/CucumberTest.java b/spring-cucumber/src/test/java/com/baeldung/CucumberTest.java new file mode 100644 index 0000000000..3e950709b3 --- /dev/null +++ b/spring-cucumber/src/test/java/com/baeldung/CucumberTest.java @@ -0,0 +1,11 @@ +package com.baeldung; + +import cucumber.api.CucumberOptions; +import cucumber.api.junit.Cucumber; +import org.junit.runner.RunWith; + + +@RunWith(Cucumber.class) +@CucumberOptions(features = "src/test/resources") +public class CucumberTest{ +} \ No newline at end of file diff --git a/spring-cucumber/src/test/java/com/baeldung/HeaderSettingRequestCallback.java b/spring-cucumber/src/test/java/com/baeldung/HeaderSettingRequestCallback.java new file mode 100644 index 0000000000..1ea72868eb --- /dev/null +++ b/spring-cucumber/src/test/java/com/baeldung/HeaderSettingRequestCallback.java @@ -0,0 +1,34 @@ +package com.baeldung; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.client.ClientHttpRequest; +import org.springframework.web.client.RequestCallback; + +import java.io.IOException; +import java.util.Map; + + +public class HeaderSettingRequestCallback implements RequestCallback{ + final Map requestHeaders; + + private String body; + + public HeaderSettingRequestCallback(final Map headers){ + this.requestHeaders = headers; + } + + public void setBody(final String postBody ){ + this.body = postBody; + } + + @Override + public void doWithRequest(ClientHttpRequest request) throws IOException{ + final HttpHeaders clientHeaders = request.getHeaders(); + for( final Map.Entry entry : requestHeaders.entrySet() ){ + clientHeaders.add(entry.getKey(),entry.getValue()); + } + if( null != body ){ + request.getBody().write( body.getBytes() ); + } + } +} \ No newline at end of file diff --git a/spring-cucumber/src/test/java/com/baeldung/OtherDefs.java b/spring-cucumber/src/test/java/com/baeldung/OtherDefs.java new file mode 100644 index 0000000000..428343d06a --- /dev/null +++ b/spring-cucumber/src/test/java/com/baeldung/OtherDefs.java @@ -0,0 +1,17 @@ +package com.baeldung; + +import cucumber.api.java.en.Given; +import cucumber.api.java.en.When; + + +public class OtherDefs extends SpringIntegrationTest{ + @When("^the client calls /baeldung$") + public void the_client_issues_POST_hello() throws Throwable{ + executePost("http://localhost:8080/baeldung"); + } + + @Given("^the client calls /hello$") + public void the_client_issues_GET_hello() throws Throwable{ + executeGet("http://localhost:8080/hello"); + } +} \ No newline at end of file diff --git a/spring-cucumber/src/test/java/com/baeldung/ResponseResults.java b/spring-cucumber/src/test/java/com/baeldung/ResponseResults.java new file mode 100644 index 0000000000..6890faf8b5 --- /dev/null +++ b/spring-cucumber/src/test/java/com/baeldung/ResponseResults.java @@ -0,0 +1,34 @@ +package com.baeldung; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; + +import org.apache.commons.io.IOUtils; +import org.springframework.http.client.ClientHttpResponse; + + +public class ResponseResults{ + private final ClientHttpResponse theResponse; + private final String body; + + protected ResponseResults(final ClientHttpResponse response) throws IOException{ + this.theResponse = response; + final InputStream bodyInputStream = response.getBody(); + if (null == bodyInputStream){ + this.body = "{}"; + }else{ + final StringWriter stringWriter = new StringWriter(); + IOUtils.copy(bodyInputStream, stringWriter); + this.body = stringWriter.toString(); + } + } + + protected ClientHttpResponse getTheResponse(){ + return theResponse; + } + + protected String getBody(){ + return body; + } +} \ No newline at end of file diff --git a/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java b/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java new file mode 100644 index 0000000000..5c85dc9400 --- /dev/null +++ b/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java @@ -0,0 +1,102 @@ +package com.baeldung; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationContextLoader; +import org.springframework.http.HttpMethod; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.web.client.ResponseErrorHandler; +import org.springframework.web.client.ResponseExtractor; +import org.springframework.web.client.RestTemplate; + + +//@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = SpringDemoApplication.class, loader = SpringApplicationContextLoader.class) +@WebAppConfiguration +@IntegrationTest +public class SpringIntegrationTest { + protected static ResponseResults latestResponse = null; + + protected RestTemplate restTemplate = null; + + protected void executeGet(String url) throws IOException{ + final Map headers = new HashMap<>(); + headers.put("Accept","application/json"); + final HeaderSettingRequestCallback requestCallback = new HeaderSettingRequestCallback(headers); + final ResponseResultErrorHandler errorHandler = new ResponseResultErrorHandler(); + + if (restTemplate == null){ + restTemplate = new RestTemplate(); + } + + restTemplate.setErrorHandler(errorHandler); + latestResponse = restTemplate.execute(url, + HttpMethod.GET, + requestCallback, + new ResponseExtractor(){ + @Override + public ResponseResults extractData(ClientHttpResponse response) throws IOException { + if (errorHandler.hadError){ + return (errorHandler.getResults()); + } else{ + return (new ResponseResults(response)); + } + } + }); + + } + + protected void executePost(String url) throws IOException{ + final Map headers = new HashMap<>(); + headers.put("Accept","application/json"); + final HeaderSettingRequestCallback requestCallback = new HeaderSettingRequestCallback(headers); + final ResponseResultErrorHandler errorHandler = new ResponseResultErrorHandler(); + + if (restTemplate == null){ + restTemplate = new RestTemplate(); + } + + restTemplate.setErrorHandler(errorHandler); + latestResponse = restTemplate.execute(url, + HttpMethod.POST, + requestCallback, + new ResponseExtractor(){ + @Override + public ResponseResults extractData(ClientHttpResponse response) throws IOException { + if (errorHandler.hadError){ + return (errorHandler.getResults()); + } else{ + return (new ResponseResults(response)); + } + } + }); + + } + + private class ResponseResultErrorHandler implements ResponseErrorHandler{ + private ResponseResults results = null; + private Boolean hadError = false; + + private ResponseResults getResults(){ + return results; + } + + @Override + public boolean hasError(ClientHttpResponse response) throws IOException{ + hadError = response.getRawStatusCode() >= 400; + return hadError; + } + + @Override + public void handleError(ClientHttpResponse response) throws IOException { + results = new ResponseResults(response); + } + } +} \ No newline at end of file diff --git a/spring-cucumber/src/test/java/com/baeldung/StepDefs.java b/spring-cucumber/src/test/java/com/baeldung/StepDefs.java new file mode 100644 index 0000000000..3ed25bb09b --- /dev/null +++ b/spring-cucumber/src/test/java/com/baeldung/StepDefs.java @@ -0,0 +1,28 @@ +package com.baeldung; + +import cucumber.api.java.en.And; +import cucumber.api.java.en.Then; +import cucumber.api.java.en.When; +import org.springframework.http.HttpStatus; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +public class StepDefs extends SpringIntegrationTest{ + + @When("^the client calls /version$") + public void the_client_issues_GET_version() throws Throwable{ + executeGet("http://localhost:8080/version"); + } + + @Then("^the client receives status code of (\\d+)$") + public void the_client_receives_status_code_of(int statusCode) throws Throwable{ + final HttpStatus currentStatusCode = latestResponse.getTheResponse().getStatusCode(); + assertThat("status code is incorrect : "+ latestResponse.getBody(), currentStatusCode.value(), is(statusCode) ); + } + + @And("^the client receives server version (.+)$") + public void the_client_receives_server_version_body(String version) throws Throwable{ + assertThat(latestResponse.getBody(), is(version)) ; + } +} \ No newline at end of file diff --git a/spring-cucumber/src/test/resources/baelung.feature b/spring-cucumber/src/test/resources/baelung.feature new file mode 100644 index 0000000000..21f18db3a4 --- /dev/null +++ b/spring-cucumber/src/test/resources/baelung.feature @@ -0,0 +1,9 @@ +Feature: the message can be retrieved + Scenario: client makes call to POST /baeldung + When the client calls /baeldung + Then the client receives status code of 200 + And the client receives server version hello + Scenario: client makes call to GET /hello + Given the client calls /hello + When the client receives status code of 200 + Then the client receives server version hello \ No newline at end of file diff --git a/spring-cucumber/src/test/resources/version.feature b/spring-cucumber/src/test/resources/version.feature new file mode 100644 index 0000000000..12f77137ff --- /dev/null +++ b/spring-cucumber/src/test/resources/version.feature @@ -0,0 +1,6 @@ +Feature: the version can be retrieved + Scenario: client makes call to GET /version + When the client calls /version + Then the client receives status code of 200 + And the client receives server version 1.0 + \ No newline at end of file diff --git a/spring-exceptions/pom.xml b/spring-exceptions/pom.xml index 554bb0c170..9ed3285018 100644 --- a/spring-exceptions/pom.xml +++ b/spring-exceptions/pom.xml @@ -130,6 +130,32 @@ test + + javax.el + el-api + 2.2 + + + + org.apache.derby + derby + 10.12.1.1 + + + org.apache.derby + derbyclient + 10.12.1.1 + + + org.apache.derby + derbynet + 10.12.1.1 + + + org.apache.derby + derbytools + 10.12.1.1 + diff --git a/spring-exceptions/src/main/java/org/baeldung/ex/nontransientexception/cause/Cause1NonTransientConfig.java b/spring-exceptions/src/main/java/org/baeldung/ex/nontransientexception/cause/Cause1NonTransientConfig.java new file mode 100644 index 0000000000..3337e4796d --- /dev/null +++ b/spring-exceptions/src/main/java/org/baeldung/ex/nontransientexception/cause/Cause1NonTransientConfig.java @@ -0,0 +1,76 @@ +package org.baeldung.ex.nontransientexception.cause; + +import java.util.Properties; + +import javax.sql.DataSource; + +import org.apache.tomcat.dbcp.dbcp.BasicDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.orm.hibernate4.HibernateTransactionManager; +import org.springframework.orm.hibernate4.LocalSessionFactoryBean; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import com.google.common.base.Preconditions; + +@Configuration +@EnableTransactionManagement +@PropertySource({ "classpath:persistence-derby.properties" }) +@ComponentScan({ "org.baeldung.persistence" }) +public class Cause1NonTransientConfig { + + @Autowired + private Environment env; + + public Cause1NonTransientConfig() { + super(); + } + + @Bean + public LocalSessionFactoryBean sessionFactory() { + final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); + sessionFactory.setDataSource(restDataSource()); + sessionFactory.setPackagesToScan(new String[] { "org.baeldung.persistence.model" }); + sessionFactory.setHibernateProperties(hibernateProperties()); + + return sessionFactory; + } + + @Bean + public DataSource restDataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); + dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); + + return dataSource; + } + + @Bean + public HibernateTransactionManager transactionManager() { + final HibernateTransactionManager txManager = new HibernateTransactionManager(); + txManager.setSessionFactory(sessionFactory().getObject()); + + return txManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + final Properties hibernateProperties() { + final Properties hibernateProperties = new Properties(); + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true"); + return hibernateProperties; + } + +} diff --git a/spring-exceptions/src/main/java/org/baeldung/ex/nontransientexception/cause/Cause4NonTransientConfig.java b/spring-exceptions/src/main/java/org/baeldung/ex/nontransientexception/cause/Cause4NonTransientConfig.java new file mode 100644 index 0000000000..3543526f37 --- /dev/null +++ b/spring-exceptions/src/main/java/org/baeldung/ex/nontransientexception/cause/Cause4NonTransientConfig.java @@ -0,0 +1,75 @@ +package org.baeldung.ex.nontransientexception.cause; + +import java.util.Properties; + +import javax.sql.DataSource; + +import org.apache.tomcat.dbcp.dbcp.BasicDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.orm.hibernate4.HibernateTransactionManager; +import org.springframework.orm.hibernate4.LocalSessionFactoryBean; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import com.google.common.base.Preconditions; + +@Configuration +@EnableTransactionManagement +@PropertySource({ "classpath:persistence-derby.properties" }) +@ComponentScan({ "org.baeldung.persistence" }) +public class Cause4NonTransientConfig { + + @Autowired + private Environment env; + + public Cause4NonTransientConfig() { + super(); + } + + @Bean + public LocalSessionFactoryBean sessionFactory() { + final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); + sessionFactory.setDataSource(restDataSource()); + sessionFactory.setPackagesToScan(new String[] { "org.baeldung.persistence.model" }); + sessionFactory.setHibernateProperties(hibernateProperties()); + + return sessionFactory; + } + + @Bean + public DataSource restDataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); + dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); + + return dataSource; + } + + @Bean + public HibernateTransactionManager transactionManager() { + final HibernateTransactionManager txManager = new HibernateTransactionManager(); + txManager.setSessionFactory(sessionFactory().getObject()); + + return txManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + final Properties hibernateProperties() { + final Properties hibernateProperties = new Properties(); + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true"); + return hibernateProperties; + } +} diff --git a/spring-exceptions/src/main/resources/persistence-derby.properties b/spring-exceptions/src/main/resources/persistence-derby.properties new file mode 100644 index 0000000000..49fac9877e --- /dev/null +++ b/spring-exceptions/src/main/resources/persistence-derby.properties @@ -0,0 +1,10 @@ +# jdbc.X +jdbc.driverClassName=org.apache.derby.jdbc.EmbeddedDriver +jdbc.url=jdbc:derby:memory:spring_exceptions;create=true +jdbc.user=tutorialuser +jdbc.pass=tutorialpass + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.DerbyDialect +hibernate.show_sql=false +hibernate.hbm2ddl.auto=create diff --git a/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/CleanupFailureExceptionTest.java b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/CleanupFailureExceptionTest.java new file mode 100644 index 0000000000..2f0a8fe09d --- /dev/null +++ b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/CleanupFailureExceptionTest.java @@ -0,0 +1,39 @@ +package org.baeldung.ex.nontransientdataaccessexception; + +import org.baeldung.ex.nontransientexception.cause.Cause1NonTransientConfig; +import org.baeldung.persistence.model.Foo; +import org.baeldung.persistence.service.IFooService; +import org.hibernate.SessionFactory; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.CleanupFailureDataAccessException; +import org.springframework.dao.NonTransientDataAccessException; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { Cause1NonTransientConfig.class }, loader = AnnotationConfigContextLoader.class) +public class CleanupFailureExceptionTest { + + @Autowired + private SessionFactory sessionFactory; + + @Autowired + private IFooService fooService; + + @Test + public void whenCleanupAfterSaving_thenCleanupException() { + try { + final Foo fooEntity = new Foo("foo"); + fooService.create(fooEntity); + } finally { + try { + sessionFactory.close(); + } catch (final NonTransientDataAccessException exc) { + throw new CleanupFailureDataAccessException("Closing connection failed", exc.getCause()); + } + } + } +} diff --git a/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataIntegrityExceptionTest.java b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataIntegrityExceptionTest.java new file mode 100644 index 0000000000..aa504223f3 --- /dev/null +++ b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataIntegrityExceptionTest.java @@ -0,0 +1,26 @@ +package org.baeldung.ex.nontransientdataaccessexception; + +import org.baeldung.ex.nontransientexception.cause.Cause1NonTransientConfig; +import org.baeldung.persistence.model.Foo; +import org.baeldung.persistence.service.IFooService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { Cause1NonTransientConfig.class }, loader = AnnotationConfigContextLoader.class) +public class DataIntegrityExceptionTest { + + @Autowired + private IFooService fooService; + + @Test(expected = DataIntegrityViolationException.class) + public void whenSavingNullValue_thenDataIntegrityException() { + final Foo fooEntity = new Foo(); + fooService.create(fooEntity); + } +} diff --git a/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataRetrievalExceptionTest.java b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataRetrievalExceptionTest.java new file mode 100644 index 0000000000..f5e24e3546 --- /dev/null +++ b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataRetrievalExceptionTest.java @@ -0,0 +1,28 @@ +package org.baeldung.ex.nontransientdataaccessexception; + +import javax.sql.DataSource; + +import org.baeldung.ex.nontransientexception.cause.Cause1NonTransientConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { Cause1NonTransientConfig.class }, loader = AnnotationConfigContextLoader.class) +public class DataRetrievalExceptionTest { + + @Autowired + private DataSource restDataSource; + + @Test(expected = DataRetrievalFailureException.class) + public void whenRetrievingNonExistentValue_thenDataRetrievalException() { + final JdbcTemplate jdbcTemplate = new JdbcTemplate(restDataSource); + + jdbcTemplate.queryForObject("select * from foo where id=3", Integer.class); + } +} diff --git a/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataSourceLookupExceptionTest.java b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataSourceLookupExceptionTest.java new file mode 100644 index 0000000000..036f99ac8f --- /dev/null +++ b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/DataSourceLookupExceptionTest.java @@ -0,0 +1,24 @@ +package org.baeldung.ex.nontransientdataaccessexception; + +import javax.sql.DataSource; + +import org.baeldung.ex.nontransientexception.cause.Cause4NonTransientConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException; +import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { Cause4NonTransientConfig.class }, loader = AnnotationConfigContextLoader.class) +public class DataSourceLookupExceptionTest { + + @Test(expected = DataSourceLookupFailureException.class) + public void whenLookupNonExistentDataSource_thenDataSourceLookupFailureException() { + final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); + dsLookup.setResourceRef(true); + final DataSource dataSource = dsLookup.getDataSource("java:comp/env/jdbc/example_db"); + } +} diff --git a/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/InvalidResourceUsageExceptionTest.java b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/InvalidResourceUsageExceptionTest.java new file mode 100644 index 0000000000..9afe2533de --- /dev/null +++ b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/InvalidResourceUsageExceptionTest.java @@ -0,0 +1,38 @@ +package org.baeldung.ex.nontransientdataaccessexception; + +import javax.sql.DataSource; + +import org.baeldung.ex.nontransientexception.cause.Cause1NonTransientConfig; +import org.baeldung.persistence.service.IFooService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.InvalidDataAccessResourceUsageException; +import org.springframework.jdbc.BadSqlGrammarException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { Cause1NonTransientConfig.class }, loader = AnnotationConfigContextLoader.class) +public class InvalidResourceUsageExceptionTest { + @Autowired + private IFooService fooService; + + @Autowired + private DataSource restDataSource; + + @Test(expected = InvalidDataAccessResourceUsageException.class) + public void whenRetrievingDataUserNoSelectRights_thenInvalidResourceUsageException() { + fooService.findAll(); + } + + @Test(expected = BadSqlGrammarException.class) + public void whenIncorrectSql_thenBadSqlGrammarException() { + final JdbcTemplate jdbcTemplate = new JdbcTemplate(restDataSource); + + jdbcTemplate.queryForObject("select * fro foo where id=3", Integer.class); + } + +} diff --git a/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/PermissionDeniedException.java b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/PermissionDeniedException.java new file mode 100644 index 0000000000..7f91b52e00 --- /dev/null +++ b/spring-exceptions/src/test/java/org/baeldung/ex/nontransientdataaccessexception/PermissionDeniedException.java @@ -0,0 +1,27 @@ +package org.baeldung.ex.nontransientdataaccessexception; + +import org.baeldung.ex.nontransientexception.cause.Cause1NonTransientConfig; +import org.baeldung.persistence.model.Foo; +import org.baeldung.persistence.service.IFooService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.PermissionDeniedDataAccessException; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { Cause1NonTransientConfig.class }, loader = AnnotationConfigContextLoader.class) +public class PermissionDeniedException { + + @Autowired + private IFooService fooService; + + @Test(expected = PermissionDeniedDataAccessException.class) + public void whenRetrievingDataUserNoSelectRights_thenPermissionDeniedException() { + final Foo foo = new Foo("foo"); + fooService.create(foo); + } + +} diff --git a/spring-mvc-velocity/pom.xml b/spring-mvc-velocity/pom.xml index 597e638cf7..6c63e0be18 100644 --- a/spring-mvc-velocity/pom.xml +++ b/spring-mvc-velocity/pom.xml @@ -128,6 +128,9 @@ org.apache.maven.plugins maven-war-plugin ${maven-war-plugin.version} + + false + diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/controller/MainController.java b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/controller/MainController.java index fe88705b90..679a455f3f 100644 --- a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/controller/MainController.java +++ b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/controller/MainController.java @@ -1,7 +1,7 @@ package com.baeldung.mvc.velocity.controller; import com.baeldung.mvc.velocity.domain.Tutorial; -import com.baeldung.mvc.velocity.service.TutorialsService; +import com.baeldung.mvc.velocity.service.ITutorialsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -14,21 +14,29 @@ import java.util.List; @RequestMapping("/") public class MainController { - private final TutorialsService tutService; - @Autowired - public MainController(TutorialsService tutService) { - this.tutService = tutService; - } + private ITutorialsService tutService; - @RequestMapping(method = RequestMethod.GET) + @RequestMapping(value ="/", method = RequestMethod.GET) + public String welcomePage() { + return "index"; + } + + + @RequestMapping(value ="/list", method = RequestMethod.GET) public String listTutorialsPage(Model model) { List list = tutService.listTutorials(); model.addAttribute("tutorials", list); - return "index"; + return "list"; } - public TutorialsService getTutService() { + public ITutorialsService getTutService() { return tutService; } + + public void setTutService(ITutorialsService tutService) { + this.tutService = tutService; + } + + } \ No newline at end of file diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/domain/Tutorial.java b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/domain/Tutorial.java index 47265aa98c..ccbaa0e905 100644 --- a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/domain/Tutorial.java +++ b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/domain/Tutorial.java @@ -14,21 +14,20 @@ public class Tutorial { this.author = author; } - public Integer getTutId() { - return tutId; - } + public Integer getTutId() { + return tutId; + } - public String getTitle() { - return title; - } + public String getTitle() { + return title; + } - public String getDescription() { - return description; - } + public String getDescription() { + return description; + } + + public String getAuthor() { + return author; + } - public String getAuthor() { - return author; - } - - } diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/MainWebAppInitializer.java b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/MainWebAppInitializer.java new file mode 100644 index 0000000000..a2871716df --- /dev/null +++ b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/MainWebAppInitializer.java @@ -0,0 +1,36 @@ +package com.baeldung.mvc.velocity.spring.config; + +import org.springframework.web.WebApplicationInitializer; +import org.springframework.web.context.ContextLoaderListener; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import org.springframework.web.context.support.GenericWebApplicationContext; +import org.springframework.web.servlet.DispatcherServlet; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; +import java.util.Set; + +public class MainWebAppInitializer implements WebApplicationInitializer { + + @Override + public void onStartup(final ServletContext sc) throws ServletException { + + // Create the 'root' Spring application context + final AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); + root.register(WebConfig.class); + + // Manages the lifecycle of the root application context + sc.addListener(new ContextLoaderListener(root)); + + // Handles requests into the application + final ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet(new GenericWebApplicationContext())); + appServlet.setLoadOnStartup(1); + + final Set mappingConflicts = appServlet.addMapping("/"); + if (!mappingConflicts.isEmpty()) { + throw new IllegalStateException("'appServlet' could not be mapped to '/' due " + "to an existing mapping. This is a known issue under Tomcat versions " + "<= 7.0.14; see https://issues.apache.org/bugzilla/show_bug.cgi?id=51278"); + } + } + +} diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/WebConfig.java b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/WebConfig.java new file mode 100644 index 0000000000..ce8ce1919a --- /dev/null +++ b/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/WebConfig.java @@ -0,0 +1,45 @@ +package com.baeldung.mvc.velocity.spring.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.view.velocity.VelocityConfigurer; +import org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver; + +@Configuration +@EnableWebMvc +@ComponentScan(basePackages = { "com.baeldung.mvc.velocity.controller", "com.baeldung.mvc.velocity.service"}) +public class WebConfig extends WebMvcConfigurerAdapter { + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); + } + + @Override + public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } + + @Bean + public ViewResolver viewResolver() { + final VelocityLayoutViewResolver bean = new VelocityLayoutViewResolver(); + bean.setCache(true); + bean.setPrefix("/WEB-INF/views/"); + bean.setLayoutUrl("/WEB-INF/layouts/layout.vm"); + bean.setSuffix(".vm"); + return bean; + } + + @Bean + public VelocityConfigurer velocityConfig() { + VelocityConfigurer velocityConfigurer = new VelocityConfigurer(); + velocityConfigurer.setResourceLoaderPath("/"); + return velocityConfigurer; + } +} diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/layouts/layout.vm b/spring-mvc-velocity/src/main/webapp/WEB-INF/layouts/layout.vm index 203e675cfb..3bac96aaae 100644 --- a/spring-mvc-velocity/src/main/webapp/WEB-INF/layouts/layout.vm +++ b/spring-mvc-velocity/src/main/webapp/WEB-INF/layouts/layout.vm @@ -1,6 +1,6 @@ - Spring & Velocity + Spring with Velocity
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/views/index.vm b/spring-mvc-velocity/src/main/webapp/WEB-INF/views/index.vm index d1ae0b02cb..8883a50658 100644 --- a/spring-mvc-velocity/src/main/webapp/WEB-INF/views/index.vm +++ b/spring-mvc-velocity/src/main/webapp/WEB-INF/views/index.vm @@ -1,19 +1,4 @@

Index

-

Tutorials list

- - - - - - - -#foreach($tut in $tutorials) - - - - - - -#end -
Tutorial IdTutorial TitleTutorial DescriptionTutorial Author
$tut.tutId$tut.title$tut.description$tut.author
\ No newline at end of file +

Welcome page

+This is just the welcome page \ No newline at end of file diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/views/list.vm b/spring-mvc-velocity/src/main/webapp/WEB-INF/views/list.vm new file mode 100644 index 0000000000..9e06a09e4f --- /dev/null +++ b/spring-mvc-velocity/src/main/webapp/WEB-INF/views/list.vm @@ -0,0 +1,19 @@ +

Index

+ +

Tutorials list

+ + + + + + + +#foreach($tut in $tutorials) + + + + + + +#end +
Tutorial IdTutorial TitleTutorial DescriptionTutorial Author
$tut.tutId$tut.title$tut.description$tut.author
\ No newline at end of file diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/web.xml b/spring-mvc-velocity/src/main/webapp/WEB-INF/web_old.xml similarity index 100% rename from spring-mvc-velocity/src/main/webapp/WEB-INF/web.xml rename to spring-mvc-velocity/src/main/webapp/WEB-INF/web_old.xml diff --git a/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/DataContentControllerTest.java b/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/DataContentControllerTest.java index 36453eef92..a9fb242755 100644 --- a/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/DataContentControllerTest.java +++ b/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/DataContentControllerTest.java @@ -1,12 +1,19 @@ package com.baeldung.mvc.velocity.test; -import com.baeldung.mvc.velocity.domain.Tutorial; -import com.baeldung.mvc.velocity.service.ITutorialsService; -import com.baeldung.mvc.velocity.service.TutorialsService; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.xpath; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -15,72 +22,40 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import java.util.Arrays; - -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.hasProperty; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; +import com.baeldung.mvc.velocity.spring.config.WebConfig; +import com.baeldung.mvc.velocity.test.config.TestConfig; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations = {"classpath:mvc-servlet.xml"}) +// @ContextConfiguration(locations = {"classpath:mvc-servlet.xml"}) +@ContextConfiguration(classes = { TestConfig.class, WebConfig.class }) @WebAppConfiguration public class DataContentControllerTest { - private MockMvc mockMvc; - @Autowired - private ITutorialsService tutServiceMock; - @Autowired private WebApplicationContext webApplicationContext; - + @Before public void setUp() { - tutServiceMock = Mockito.mock(TutorialsService.class); - Mockito.reset(tutServiceMock); + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); } - - @Test - public void testModel() throws Exception{ - Mockito.when(tutServiceMock.listTutorials()).thenReturn(Arrays.asList( - new Tutorial(1, "Guava", "Introduction to Guava", "GuavaAuthor"), - new Tutorial(2, "Android", "Introduction to Android", "AndroidAuthor") - )); - - mockMvc.perform(get("/")) - .andExpect(status().isOk()) - .andExpect(view().name("index")) - .andExpect(content().string(containsString("GuavaAuthor"))) - .andExpect(content().string(containsString("Introduction to Guava"))) - .andExpect(content().string(containsString("AndroidAuthor"))) - .andExpect(content().string(containsString("Introduction to Android"))) - .andExpect(model().attribute("tutorials", hasSize(2))) - .andExpect(model().attribute("tutorials", hasSize(2))) - .andExpect(model().attribute("tutorials", hasItem( - allOf( - hasProperty("tutId", is(1)), - hasProperty("author", is("GuavaAuthor")), - hasProperty("title", is("Guava")) - ) - ))) - .andExpect(model().attribute("tutorials", hasItem( - allOf( - hasProperty("tutId", is(2)), - hasProperty("author", is("AndroidAuthor")), - hasProperty("title", is("Android")) - ) - ))); - } + @Test + public void whenCallingList_ThenModelAndContentOK() throws Exception { + + mockMvc.perform(get("/list")).andExpect(status().isOk()).andExpect(view().name("list")).andExpect(model().attribute("tutorials", hasSize(2))) + .andExpect(model().attribute("tutorials", hasItem(allOf(hasProperty("tutId", is(1)), hasProperty("author", is("GuavaAuthor")), hasProperty("title", is("Guava")))))) + .andExpect(model().attribute("tutorials", hasItem(allOf(hasProperty("tutId", is(2)), hasProperty("author", is("AndroidAuthor")), hasProperty("title", is("Android")))))); + + mockMvc.perform(get("/list")).andExpect(xpath("//table").exists()); + mockMvc.perform(get("/list")).andExpect(xpath("//td[@id='tutId_1']").exists()); + } + + @Test + public void whenCallingIndex_thenViewOK() throws Exception{ + mockMvc.perform(get("/")).andExpect(status().isOk()).andExpect(view().name("index")).andExpect(model().size(0)); + } } diff --git a/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/NavigationControllerTest.java b/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/NavigationControllerTest.java deleted file mode 100644 index e007cf3f94..0000000000 --- a/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/NavigationControllerTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.baeldung.mvc.velocity.test; - - -import com.baeldung.mvc.velocity.controller.MainController; -import com.baeldung.mvc.velocity.domain.Tutorial; -import com.baeldung.mvc.velocity.service.TutorialsService; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.ui.ExtendedModelMap; -import org.springframework.ui.Model; - -import java.util.Arrays; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -@RunWith(SpringJUnit4ClassRunner.class) -@WebAppConfiguration -@ContextConfiguration(locations = {"classpath:mvc-servlet.xml"}) -public class NavigationControllerTest { - - private MainController mainController = new MainController(Mockito.mock(TutorialsService.class)); - - private final Model model = new ExtendedModelMap(); - - - @Test - public void shouldGoToTutorialListView() { - Mockito.when(mainController.getTutService().listTutorials()) - .thenReturn(createTutorialList()); - - final String view = mainController.listTutorialsPage(model); - final List tutorialListAttribute = (List) model.asMap().get("tutorials"); - - assertEquals("index", view); - assertNotNull(tutorialListAttribute); - } - - @Test - public void testContent() throws Exception{ - - List tutorials = Arrays.asList( - new Tutorial(1, "Guava", "Introduction to Guava", "GuavaAuthor"), - new Tutorial(2, "Android", "Introduction to Android", "AndroidAuthor") - ); - Mockito.when(mainController.getTutService().listTutorials()).thenReturn(tutorials); - - String view = mainController.listTutorialsPage(model); - - verify(mainController.getTutService(), times(1)).listTutorials(); - verifyNoMoreInteractions(mainController.getTutService()); - - assertEquals("index", view); - assertEquals(tutorials, model.asMap().get("tutorials")); - } - - private static List createTutorialList() { - return Arrays.asList(new Tutorial(1, "TestAuthor", "Test Title", "Test Description")); - } -} diff --git a/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/config/TestConfig.java b/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/config/TestConfig.java new file mode 100644 index 0000000000..8b84bcdd23 --- /dev/null +++ b/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/config/TestConfig.java @@ -0,0 +1,32 @@ +package com.baeldung.mvc.velocity.test.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.view.velocity.VelocityConfigurer; +import org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver; + +@Configuration +public class TestConfig { + + + @Bean + public ViewResolver viewResolver() { + final VelocityLayoutViewResolver bean = new VelocityLayoutViewResolver(); + bean.setCache(true); + bean.setPrefix("/WEB-INF/views/"); + bean.setLayoutUrl("/WEB-INF/layouts/layout.vm"); + bean.setSuffix(".vm"); + return bean; + } + + @Bean + public VelocityConfigurer velocityConfig() { + VelocityConfigurer velocityConfigurer = new VelocityConfigurer(); + velocityConfigurer.setResourceLoaderPath("/"); + return velocityConfigurer; + } + + + +} diff --git a/spring-rest-angular-pagination/StudentDirectory/pom.xml b/spring-rest-angular-pagination/StudentDirectory/pom.xml new file mode 100644 index 0000000000..8dab851ef2 --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/pom.xml @@ -0,0 +1,86 @@ + + + 4.0.0 + angular-spring-rest-sample + angular-spring-rest-sample + com.baeldung + 1.0 + war + + org.springframework.boot + spring-boot-starter-parent + 1.3.3.RELEASE + + + 1.12.2.RELEASE + + + + org.springframework.boot + spring-boot-starter-tomcat + provided + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.data + spring-data-commons + + + org.springframework + spring-test + test + + + org.apache.commons + commons-lang3 + 3.3 + + + com.google.guava + guava + 19.0 + + + junit + junit + test + + + io.rest-assured + rest-assured + 3.0.0 + test + + + io.rest-assured + spring-mock-mvc + 3.0.0 + test + + + + angular-spring-rest-sample + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-war-plugin + + false + + + + + diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/mock/MockStudentData.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/mock/MockStudentData.java new file mode 100644 index 0000000000..df70780a87 --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/mock/MockStudentData.java @@ -0,0 +1,39 @@ +package org.baeldung.mock; + +import java.util.ArrayList; +import java.util.List; + +import org.baeldung.web.vo.Student; + +public class MockStudentData { + + private static List studentList = new ArrayList<>(); + + static { + studentList.add(new Student("1", "Bryan", "Male", 20)); + studentList.add(new Student("2", "Ben", "Male", 22)); + studentList.add(new Student("3", "Lisa", "Female", 24)); + studentList.add(new Student("4", "Sarah", "Female", 26)); + studentList.add(new Student("5", "Jay", "Male", 20)); + studentList.add(new Student("6", "John", "Male", 22)); + studentList.add(new Student("7", "Jordan", "Male", 24)); + studentList.add(new Student("8", "Rob", "Male", 26)); + studentList.add(new Student("9", "Will", "Male", 20)); + studentList.add(new Student("10", "Shawn", "Male", 22)); + studentList.add(new Student("11", "Taylor", "Female", 24)); + studentList.add(new Student("12", "Venus", "Female", 26)); + studentList.add(new Student("13", "Vince", "Male", 20)); + studentList.add(new Student("14", "Carol", "Female", 22)); + studentList.add(new Student("15", "Joana", "Female", 24)); + studentList.add(new Student("16", "Dion", "Male", 26)); + studentList.add(new Student("17", "Evans", "Male", 20)); + studentList.add(new Student("18", "Bart", "Male", 22)); + studentList.add(new Student("19", "Jenny", "Female", 24)); + studentList.add(new Student("20", "Kristine", "Female", 26)); + } + + public static List getMockDataStudents(){ + return studentList; + } + +} diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/exception/MyResourceNotFoundException.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/exception/MyResourceNotFoundException.java new file mode 100644 index 0000000000..3105d1cb11 --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/exception/MyResourceNotFoundException.java @@ -0,0 +1,27 @@ +package org.baeldung.web.exception; + +public class MyResourceNotFoundException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = 4088649120307193208L; + + public MyResourceNotFoundException() { + super(); + } + + public MyResourceNotFoundException(final String message, final Throwable cause) { + super(message, cause); + } + + public MyResourceNotFoundException(final String message) { + super(message); + } + + public MyResourceNotFoundException(final Throwable cause) { + super(cause); + } + + +} diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/main/Application.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/main/Application.java new file mode 100644 index 0000000000..b3b0dad98a --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/main/Application.java @@ -0,0 +1,26 @@ +package org.baeldung.web.main; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.web.filter.ShallowEtagHeaderFilter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +@SpringBootApplication +@EnableAutoConfiguration +@ComponentScan("org.baeldung") +public class Application extends WebMvcConfigurerAdapter { + + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @Bean + public ShallowEtagHeaderFilter shallowEtagHeaderFilter() { + return new ShallowEtagHeaderFilter(); + } + +} diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/rest/StudentDirectoryRestController.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/rest/StudentDirectoryRestController.java new file mode 100644 index 0000000000..5ff24ec0f2 --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/rest/StudentDirectoryRestController.java @@ -0,0 +1,26 @@ +package org.baeldung.web.rest; + +import org.baeldung.web.service.StudentService; +import org.baeldung.web.vo.Student; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class StudentDirectoryRestController { + + @Autowired + private StudentService service; + + @RequestMapping(value = "/student/get", params = { "page", "size" }, method = RequestMethod.GET) + public Page findPaginated(@RequestParam("page") int page, @RequestParam("size") int size){ + + Page resultPage = service.findPaginated(page, size); + + return resultPage; + } + +} diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/IOperations.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/IOperations.java new file mode 100644 index 0000000000..0b408106ce --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/IOperations.java @@ -0,0 +1,9 @@ +package org.baeldung.web.service; + +import org.springframework.data.domain.Page; + +public interface IOperations { + + Page findPaginated(int page, int size); + +} diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentService.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentService.java new file mode 100644 index 0000000000..5c4487254a --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentService.java @@ -0,0 +1,7 @@ +package org.baeldung.web.service; + +import org.baeldung.web.vo.Student; + +public interface StudentService extends IOperations{ + +} diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentServiceImpl.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentServiceImpl.java new file mode 100644 index 0000000000..3b6dda6fb1 --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/service/StudentServiceImpl.java @@ -0,0 +1,36 @@ +package org.baeldung.web.service; + +import java.util.List; + +import org.baeldung.mock.MockStudentData; +import org.baeldung.web.exception.MyResourceNotFoundException; +import org.baeldung.web.vo.Student; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; + +@Service +public class StudentServiceImpl implements StudentService { + + private List mockDataStudent = MockStudentData.getMockDataStudents(); + + @Override + public Page findPaginated(int page, int size){ + Page studentPage = getPage(page, size); + return studentPage; + } + + private Page getPage(int page, int size) { + page = page != 0?page - 1:page; + int from = Math.max(0, page * size); + int to = Math.min(mockDataStudent.size(), (page + 1) * size); + if(from > to){ + throw new MyResourceNotFoundException("page number is higher than total pages."); + } + return new PageImpl(mockDataStudent.subList(from, to), + new PageRequest(page,size), + mockDataStudent.size()); + } + +} diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/vo/Student.java b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/vo/Student.java new file mode 100644 index 0000000000..11c503815d --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/src/main/java/org/baeldung/web/vo/Student.java @@ -0,0 +1,60 @@ +package org.baeldung.web.vo; + +import java.io.Serializable; + +public class Student implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public Student() { + } + + public Student(String studentId, String name, String gender, Integer age) { + super(); + this.studentId = studentId; + this.name = name; + this.gender = gender; + this.age = age; + } + + private String studentId; + private String name; + private String gender; + private Integer age; + + public String getStudentId() { + return studentId; + } + + public void setStudentId(String studentId) { + this.studentId = studentId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getGender() { + return gender; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + +} diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/resources/application.properties b/spring-rest-angular-pagination/StudentDirectory/src/main/resources/application.properties new file mode 100644 index 0000000000..a9bf6ca218 --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/src/main/resources/application.properties @@ -0,0 +1 @@ +server.contextPath=/StudentDirectory \ No newline at end of file diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/WEB-INF/web.xml b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..ff65bd6b96 --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,11 @@ + + + + + index.html + + + \ No newline at end of file diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/index.html b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/index.html new file mode 100644 index 0000000000..56a1273588 --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/index.html @@ -0,0 +1,14 @@ + + + + + + + + + +
+
+
+ + \ No newline at end of file diff --git a/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/view/app.js b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/view/app.js new file mode 100644 index 0000000000..522c49c8cb --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/src/main/webapp/view/app.js @@ -0,0 +1,54 @@ +var app = angular.module('app', ['ui.grid','ui.grid.pagination']); + +app.controller('StudentCtrl', ['$scope','StudentService', function ($scope,StudentService) { + var paginationOptions = { + pageNumber: 1, + pageSize: 5, + sort: null + }; + + StudentService.getStudents(paginationOptions.pageNumber, + paginationOptions.pageSize).success(function(data){ + $scope.gridOptions.data = data.content; + $scope.gridOptions.totalItems = data.totalElements; + }); + + $scope.gridOptions = { + paginationPageSizes: [5, 10, 20], + paginationPageSize: paginationOptions.pageSize, + enableColumnMenus:false, + columnDefs: [ + { name: 'studentId' }, + { name: 'name' }, + { name: 'gender' }, + { name: 'age' } + ], + onRegisterApi: function(gridApi) { + $scope.gridApi = gridApi; + gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) { + paginationOptions.pageNumber = newPage; + paginationOptions.pageSize = pageSize; + StudentService.getStudents(newPage,pageSize).success(function(data){ + $scope.gridOptions.data = data.content; + $scope.gridOptions.totalItems = data.totalElements; + }); + }); + } + }; + +}]); + +app.service('StudentService',['$http', function ($http) { + + function getStudents(pageNumber,size) { + return $http({ + method: 'GET', + url: 'student/get?page='+pageNumber+'&size='+size + }); + } + + return { + getStudents:getStudents + }; + +}]); \ No newline at end of file diff --git a/spring-rest-angular-pagination/StudentDirectory/src/test/java/org/baeldung/web/service/StudentServiceTest.java b/spring-rest-angular-pagination/StudentDirectory/src/test/java/org/baeldung/web/service/StudentServiceTest.java new file mode 100644 index 0000000000..3e476bf0d0 --- /dev/null +++ b/spring-rest-angular-pagination/StudentDirectory/src/test/java/org/baeldung/web/service/StudentServiceTest.java @@ -0,0 +1,49 @@ +package org.baeldung.web.service; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.apache.commons.lang3.RandomStringUtils; +import org.baeldung.web.main.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import io.restassured.RestAssured; +import io.restassured.response.Response; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@IntegrationTest("server.port:8080") +public class StudentServiceTest{ + + private String getURL() { + return "/StudentDirectory/student/get"; + } + + @Test + public void whenResourcesAreRetrievedPaged_then200IsReceived(){ + Response response = RestAssured.given().get(getURL()+ "?page=0&size=2").andReturn(); + + assertTrue(response.getStatusCode() == 200 ); + } + + @Test + public void whenPageOfResourcesAreRetrievedOutOfBounds_then404IsReceived(){ + String url = getURL()+ "?page=" + RandomStringUtils.randomNumeric(5) + "&size=2"; + Response response = RestAssured.given().get(url); + + assertTrue(response.getStatusCode() == 500 ); + } + + @Test + public void givenResourcesExist_whenFirstPageIsRetrieved_thenPageContainsResources(){ + Response response = RestAssured.given().get(getURL() + "?page=1&size=2" ); + assertFalse(response.getBody().jsonPath().getList("content").isEmpty() ); + } + +} diff --git a/spring-rest-docs/src/main/java/com/example/CRUDController.java b/spring-rest-docs/src/main/java/com/example/CRUDController.java index 818b29d3a6..ff8c91d6cd 100644 --- a/spring-rest-docs/src/main/java/com/example/CRUDController.java +++ b/spring-rest-docs/src/main/java/com/example/CRUDController.java @@ -17,39 +17,39 @@ import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/crud") public class CRUDController { - - @RequestMapping(method=RequestMethod.GET) - @ResponseStatus(HttpStatus.OK) - public List read(@RequestBody CrudInput crudInput) { - List returnList=new ArrayList(); - returnList.add(crudInput); - return returnList; - } - - @ResponseStatus(HttpStatus.CREATED) - @RequestMapping(method=RequestMethod.POST) - public HttpHeaders save(@RequestBody CrudInput crudInput) { - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.setLocation(linkTo(CRUDController.class).slash(crudInput.getTitle()).toUri()); - return httpHeaders; - } - - @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) - @ResponseStatus(HttpStatus.OK) - HttpHeaders delete(@RequestBody CrudInput crudInput) { - HttpHeaders httpHeaders = new HttpHeaders(); - return httpHeaders; - } - - @RequestMapping(value = "/{id}", method = RequestMethod.PUT) - @ResponseStatus(HttpStatus.ACCEPTED) - void put(@PathVariable("id") long id, @RequestBody CrudInput crudInput) { - - } - - @RequestMapping(value = "/{id}", method = RequestMethod.PATCH) - @ResponseStatus(HttpStatus.NO_CONTENT) - void patch(@PathVariable("id") long id, @RequestBody CrudInput crudInput) { - - } + + @RequestMapping(method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + public List read(@RequestBody CrudInput crudInput) { + List returnList = new ArrayList(); + returnList.add(crudInput); + return returnList; + } + + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(method = RequestMethod.POST) + public HttpHeaders save(@RequestBody CrudInput crudInput) { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setLocation(linkTo(CRUDController.class).slash(crudInput.getTitle()).toUri()); + return httpHeaders; + } + + @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) + @ResponseStatus(HttpStatus.OK) + HttpHeaders delete(@RequestBody CrudInput crudInput) { + HttpHeaders httpHeaders = new HttpHeaders(); + return httpHeaders; + } + + @RequestMapping(value = "/{id}", method = RequestMethod.PUT) + @ResponseStatus(HttpStatus.ACCEPTED) + void put(@PathVariable("id") long id, @RequestBody CrudInput crudInput) { + + } + + @RequestMapping(value = "/{id}", method = RequestMethod.PATCH) + @ResponseStatus(HttpStatus.NO_CONTENT) + void patch(@PathVariable("id") long id, @RequestBody CrudInput crudInput) { + + } } diff --git a/spring-rest-docs/src/main/java/com/example/CrudInput.java b/spring-rest-docs/src/main/java/com/example/CrudInput.java index 3d91b7d45a..36ad67eb21 100644 --- a/spring-rest-docs/src/main/java/com/example/CrudInput.java +++ b/spring-rest-docs/src/main/java/com/example/CrudInput.java @@ -10,33 +10,32 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; public class CrudInput { - - //@NotBlank - private final String title; - private final String body; + // @NotBlank + private final String title; - private final List tagUris; + private final String body; - @JsonCreator - public CrudInput(@JsonProperty("title") String title, - @JsonProperty("body") String body, @JsonProperty("tags") List tagUris) { - this.title = title; - this.body = body; - this.tagUris = tagUris == null ? Collections.emptyList() : tagUris; - } + private final List tagUris; - public String getTitle() { - return title; - } + @JsonCreator + public CrudInput(@JsonProperty("title") String title, @JsonProperty("body") String body, @JsonProperty("tags") List tagUris) { + this.title = title; + this.body = body; + this.tagUris = tagUris == null ? Collections. emptyList() : tagUris; + } - public String getBody() { - return body; - } + public String getTitle() { + return title; + } - @JsonProperty("tags") - public List getTagUris() { - return this.tagUris; - } + public String getBody() { + return body; + } + + @JsonProperty("tags") + public List getTagUris() { + return this.tagUris; + } } \ No newline at end of file diff --git a/spring-rest-docs/src/main/java/com/example/IndexController.java b/spring-rest-docs/src/main/java/com/example/IndexController.java index a6b4537c43..6b896da416 100644 --- a/spring-rest-docs/src/main/java/com/example/IndexController.java +++ b/spring-rest-docs/src/main/java/com/example/IndexController.java @@ -1,6 +1,5 @@ package com.example; - import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import org.springframework.hateoas.ResourceSupport; @@ -12,11 +11,11 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping("/") public class IndexController { - @RequestMapping(method=RequestMethod.GET) - public ResourceSupport index() { - ResourceSupport index = new ResourceSupport(); - index.add(linkTo(CRUDController.class).withRel("crud")); - return index; - } + @RequestMapping(method = RequestMethod.GET) + public ResourceSupport index() { + ResourceSupport index = new ResourceSupport(); + index.add(linkTo(CRUDController.class).withRel("crud")); + return index; + } } \ No newline at end of file diff --git a/spring-rest-docs/src/main/java/com/example/SpringRestDocsApplication.java b/spring-rest-docs/src/main/java/com/example/SpringRestDocsApplication.java index dd20ef324e..da09f9accc 100644 --- a/spring-rest-docs/src/main/java/com/example/SpringRestDocsApplication.java +++ b/spring-rest-docs/src/main/java/com/example/SpringRestDocsApplication.java @@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringRestDocsApplication { - public static void main(String[] args) { - SpringApplication.run(SpringRestDocsApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(SpringRestDocsApplication.class, args); + } } diff --git a/spring-rest-docs/src/test/java/com/example/ApiDocumentation.java b/spring-rest-docs/src/test/java/com/example/ApiDocumentation.java index 195b9dc514..5b753aff0c 100644 --- a/spring-rest-docs/src/test/java/com/example/ApiDocumentation.java +++ b/spring-rest-docs/src/test/java/com/example/ApiDocumentation.java @@ -56,55 +56,35 @@ public class ApiDocumentation { @Before public void setUp() { this.document = document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())); - this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context) - .apply(documentationConfiguration(this.restDocumentation)) - .alwaysDo(this.document) - .build(); + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).apply(documentationConfiguration(this.restDocumentation)).alwaysDo(this.document).build(); } - @Test public void headersExample() throws Exception { - this.document.snippets(responseHeaders(headerWithName("Content-Type") - .description("The Content-Type of the payload, e.g. `application/hal+json`"))); - this.mockMvc.perform(get("/")) - .andExpect(status().isOk()); + this.document.snippets(responseHeaders(headerWithName("Content-Type").description("The Content-Type of the payload, e.g. `application/hal+json`"))); + this.mockMvc.perform(get("/")).andExpect(status().isOk()); } @Test public void indexExample() throws Exception { - this.document.snippets( - links(linkWithRel("crud").description("The <>")), - responseFields(fieldWithPath("_links").description("<> to other resources")) - ); - this.mockMvc.perform(get("/")) - .andExpect(status().isOk()); + this.document.snippets(links(linkWithRel("crud").description("The <>")), responseFields(fieldWithPath("_links").description("<> to other resources"))); + this.mockMvc.perform(get("/")).andExpect(status().isOk()); } - @Test public void crudGetExample() throws Exception { Map tag = new HashMap<>(); tag.put("name", "GET"); - String tagLocation = this.mockMvc.perform(get("/crud") - .contentType(MediaTypes.HAL_JSON) - .content(this.objectMapper.writeValueAsString(tag))) - .andExpect(status().isOk()) - .andReturn() - .getResponse() - .getHeader("Location"); + String tagLocation = this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isOk()).andReturn().getResponse().getHeader("Location"); Map crud = new HashMap<>(); crud.put("title", "Sample Model"); crud.put("body", "http://www.baeldung.com/"); crud.put("tags", singletonList(tagLocation)); - this.mockMvc.perform(get("/crud") - .contentType(MediaTypes.HAL_JSON) - .content(this.objectMapper.writeValueAsString(crud))) - .andExpect(status().isOk()); + this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isOk()); } @Test @@ -112,13 +92,7 @@ public class ApiDocumentation { Map tag = new HashMap<>(); tag.put("name", "CREATE"); - String tagLocation = this.mockMvc.perform(post("/crud") - .contentType(MediaTypes.HAL_JSON) - .content(this.objectMapper.writeValueAsString(tag))) - .andExpect(status().isCreated()) - .andReturn() - .getResponse() - .getHeader("Location"); + String tagLocation = this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isCreated()).andReturn().getResponse().getHeader("Location"); Map crud = new HashMap<>(); crud.put("title", "Sample Model"); @@ -126,13 +100,9 @@ public class ApiDocumentation { crud.put("tags", singletonList(tagLocation)); ConstrainedFields fields = new ConstrainedFields(CrudInput.class); - this.document.snippets(requestFields( - fields.withPath("title").description("The title of the note"), - fields.withPath("body").description("The body of the note"), - fields.withPath("tags").description("An array of tag resource URIs"))); + this.document.snippets(requestFields(fields.withPath("title").description("The title of the note"), fields.withPath("body").description("The body of the note"), fields.withPath("tags").description("An array of tag resource URIs"))); this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isCreated()); - } @Test @@ -141,23 +111,14 @@ public class ApiDocumentation { Map tag = new HashMap<>(); tag.put("name", "DELETE"); - String tagLocation = this.mockMvc.perform(delete("/crud/10") - .contentType(MediaTypes.HAL_JSON) - .content(this.objectMapper.writeValueAsString(tag))) - .andExpect(status().isOk()) - .andReturn() - .getResponse() - .getHeader("Location"); + String tagLocation = this.mockMvc.perform(delete("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isOk()).andReturn().getResponse().getHeader("Location"); Map crud = new HashMap<>(); crud.put("title", "Sample Model"); crud.put("body", "http://www.baeldung.com/"); crud.put("tags", singletonList(tagLocation)); - this.mockMvc.perform(delete("/crud/10") - .contentType(MediaTypes.HAL_JSON) - .content(this.objectMapper.writeValueAsString(crud))) - .andExpect(status().isOk()); + this.mockMvc.perform(delete("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isOk()); } @Test @@ -166,51 +127,31 @@ public class ApiDocumentation { Map tag = new HashMap<>(); tag.put("name", "PATCH"); - String tagLocation = this.mockMvc.perform(patch("/crud/10") - .contentType(MediaTypes.HAL_JSON) - .content(this.objectMapper.writeValueAsString(tag))) - .andExpect(status().isNoContent()) - .andReturn() - .getResponse() - .getHeader("Location"); + String tagLocation = this.mockMvc.perform(patch("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isNoContent()).andReturn().getResponse().getHeader("Location"); Map crud = new HashMap<>(); crud.put("title", "Sample Model"); crud.put("body", "http://www.baeldung.com/"); crud.put("tags", singletonList(tagLocation)); - this.mockMvc.perform(patch("/crud/10") - .contentType(MediaTypes.HAL_JSON) - .content(this.objectMapper.writeValueAsString(crud))) - .andExpect(status().isNoContent()); + this.mockMvc.perform(patch("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isNoContent()); } - @Test public void crudPutExample() throws Exception { Map tag = new HashMap<>(); tag.put("name", "PUT"); - String tagLocation = this.mockMvc.perform(put("/crud/10") - .contentType(MediaTypes.HAL_JSON) - .content(this.objectMapper.writeValueAsString(tag))) - .andExpect(status().isAccepted()) - .andReturn() - .getResponse() - .getHeader("Location"); + String tagLocation = this.mockMvc.perform(put("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(tag))).andExpect(status().isAccepted()).andReturn().getResponse().getHeader("Location"); Map crud = new HashMap<>(); crud.put("title", "Sample Model"); crud.put("body", "http://www.baeldung.com/"); crud.put("tags", singletonList(tagLocation)); - this.mockMvc.perform(put("/crud/10") - .contentType(MediaTypes.HAL_JSON) - .content(this.objectMapper.writeValueAsString(crud))) - .andExpect(status().isAccepted()); + this.mockMvc.perform(put("/crud/10").contentType(MediaTypes.HAL_JSON).content(this.objectMapper.writeValueAsString(crud))).andExpect(status().isAccepted()); } - @Test public void contextLoads() { } @@ -224,11 +165,8 @@ public class ApiDocumentation { } private FieldDescriptor withPath(String path) { - return fieldWithPath(path) - .attributes(key("constraints") - .value(collectionToDelimitedString(this.constraintDescriptions.descriptionsForProperty(path), ". "))); + return fieldWithPath(path).attributes(key("constraints").value(collectionToDelimitedString(this.constraintDescriptions.descriptionsForProperty(path), ". "))); } } - } diff --git a/spring-rest-docs/src/test/java/com/example/GettingStartedDocumentation.java b/spring-rest-docs/src/test/java/com/example/GettingStartedDocumentation.java index 7f3c4db1f9..7aea9d303c 100644 --- a/spring-rest-docs/src/test/java/com/example/GettingStartedDocumentation.java +++ b/spring-rest-docs/src/test/java/com/example/GettingStartedDocumentation.java @@ -46,113 +46,105 @@ public class GettingStartedDocumentation { private MockMvc mockMvc; - @Before public void setUp() { - this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context) - .apply(documentationConfiguration(this.restDocumentation)) - .alwaysDo(document("{method-name}/{step}/", - preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()))) - .build(); + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).apply(documentationConfiguration(this.restDocumentation)).alwaysDo(document("{method-name}/{step}/", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()))).build(); } @Test public void index() throws Exception { - this.mockMvc.perform(get("/").accept(MediaTypes.HAL_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("_links.crud", is(notNullValue()))) - .andExpect(jsonPath("_links.crud", is(notNullValue()))); + this.mockMvc.perform(get("/").accept(MediaTypes.HAL_JSON)).andExpect(status().isOk()).andExpect(jsonPath("_links.crud", is(notNullValue()))).andExpect(jsonPath("_links.crud", is(notNullValue()))); } -// String createNote() throws Exception { -// Map note = new HashMap(); -// note.put("title", "Note creation with cURL"); -// note.put("body", "An example of how to create a note using curl"); -// String noteLocation = this.mockMvc.perform(post("/crud") -// .contentType(MediaTypes.HAL_JSON) -// .content(objectMapper.writeValueAsString(note))) -// .andExpect(status().isCreated()) -// .andExpect(header().string("Location", notNullValue())) -// .andReturn() -// .getResponse() -// .getHeader("Location"); -// return noteLocation; -// } -// -// MvcResult getNote(String noteLocation) throws Exception { -// return this.mockMvc.perform(get(noteLocation)) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("title", is(notNullValue()))) -// .andExpect(jsonPath("body", is(notNullValue()))) -// .andExpect(jsonPath("_links.crud", is(notNullValue()))) -// .andReturn(); -// } -// -// -// String createTag() throws Exception, JsonProcessingException { -// Map tag = new HashMap(); -// tag.put("name", "getting-started"); -// String tagLocation = this.mockMvc.perform(post("/crud") -// .contentType(MediaTypes.HAL_JSON) -// .content(objectMapper.writeValueAsString(tag))) -// .andExpect(status().isCreated()) -// .andExpect(header().string("Location", notNullValue())) -// .andReturn() -// .getResponse() -// .getHeader("Location"); -// return tagLocation; -// } -// -// void getTag(String tagLocation) throws Exception { -// this.mockMvc.perform(get(tagLocation)).andExpect(status().isOk()) -// .andExpect(jsonPath("name", is(notNullValue()))) -// .andExpect(jsonPath("_links.tagged-notes", is(notNullValue()))); -// } -// -// String createTaggedNote(String tag) throws Exception { -// Map note = new HashMap(); -// note.put("title", "Tagged note creation with cURL"); -// note.put("body", "An example of how to create a tagged note using cURL"); -// note.put("tags", Arrays.asList(tag)); -// -// String noteLocation = this.mockMvc.perform(post("/notes") -// .contentType(MediaTypes.HAL_JSON) -// .content(objectMapper.writeValueAsString(note))) -// .andExpect(status().isCreated()) -// .andExpect(header().string("Location", notNullValue())) -// .andReturn() -// .getResponse() -// .getHeader("Location"); -// return noteLocation; -// } -// -// void getTags(String noteTagsLocation) throws Exception { -// this.mockMvc.perform(get(noteTagsLocation)) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("_embedded.tags", hasSize(1))); -// } -// -// void tagExistingNote(String noteLocation, String tagLocation) throws Exception { -// Map update = new HashMap(); -// update.put("tags", Arrays.asList(tagLocation)); -// this.mockMvc.perform(patch(noteLocation) -// .contentType(MediaTypes.HAL_JSON) -// .content(objectMapper.writeValueAsString(update))) -// .andExpect(status().isNoContent()); -// } -// -// MvcResult getTaggedExistingNote(String noteLocation) throws Exception { -// return this.mockMvc.perform(get(noteLocation)).andExpect(status().isOk()).andReturn(); -// } -// -// void getTagsForExistingNote(String noteTagsLocation) throws Exception { -// this.mockMvc.perform(get(noteTagsLocation)) -// .andExpect(status().isOk()).andExpect(jsonPath("_embedded.tags", hasSize(1))); -// } -// -// private String getLink(MvcResult result, String rel) -// throws UnsupportedEncodingException { -// return JsonPath.parse(result.getResponse().getContentAsString()).read("_links." + rel + ".href"); -// } + // String createNote() throws Exception { + // Map note = new HashMap(); + // note.put("title", "Note creation with cURL"); + // note.put("body", "An example of how to create a note using curl"); + // String noteLocation = this.mockMvc.perform(post("/crud") + // .contentType(MediaTypes.HAL_JSON) + // .content(objectMapper.writeValueAsString(note))) + // .andExpect(status().isCreated()) + // .andExpect(header().string("Location", notNullValue())) + // .andReturn() + // .getResponse() + // .getHeader("Location"); + // return noteLocation; + // } + // + // MvcResult getNote(String noteLocation) throws Exception { + // return this.mockMvc.perform(get(noteLocation)) + // .andExpect(status().isOk()) + // .andExpect(jsonPath("title", is(notNullValue()))) + // .andExpect(jsonPath("body", is(notNullValue()))) + // .andExpect(jsonPath("_links.crud", is(notNullValue()))) + // .andReturn(); + // } + // + // + // String createTag() throws Exception, JsonProcessingException { + // Map tag = new HashMap(); + // tag.put("name", "getting-started"); + // String tagLocation = this.mockMvc.perform(post("/crud") + // .contentType(MediaTypes.HAL_JSON) + // .content(objectMapper.writeValueAsString(tag))) + // .andExpect(status().isCreated()) + // .andExpect(header().string("Location", notNullValue())) + // .andReturn() + // .getResponse() + // .getHeader("Location"); + // return tagLocation; + // } + // + // void getTag(String tagLocation) throws Exception { + // this.mockMvc.perform(get(tagLocation)).andExpect(status().isOk()) + // .andExpect(jsonPath("name", is(notNullValue()))) + // .andExpect(jsonPath("_links.tagged-notes", is(notNullValue()))); + // } + // + // String createTaggedNote(String tag) throws Exception { + // Map note = new HashMap(); + // note.put("title", "Tagged note creation with cURL"); + // note.put("body", "An example of how to create a tagged note using cURL"); + // note.put("tags", Arrays.asList(tag)); + // + // String noteLocation = this.mockMvc.perform(post("/notes") + // .contentType(MediaTypes.HAL_JSON) + // .content(objectMapper.writeValueAsString(note))) + // .andExpect(status().isCreated()) + // .andExpect(header().string("Location", notNullValue())) + // .andReturn() + // .getResponse() + // .getHeader("Location"); + // return noteLocation; + // } + // + // void getTags(String noteTagsLocation) throws Exception { + // this.mockMvc.perform(get(noteTagsLocation)) + // .andExpect(status().isOk()) + // .andExpect(jsonPath("_embedded.tags", hasSize(1))); + // } + // + // void tagExistingNote(String noteLocation, String tagLocation) throws Exception { + // Map update = new HashMap(); + // update.put("tags", Arrays.asList(tagLocation)); + // this.mockMvc.perform(patch(noteLocation) + // .contentType(MediaTypes.HAL_JSON) + // .content(objectMapper.writeValueAsString(update))) + // .andExpect(status().isNoContent()); + // } + // + // MvcResult getTaggedExistingNote(String noteLocation) throws Exception { + // return this.mockMvc.perform(get(noteLocation)).andExpect(status().isOk()).andReturn(); + // } + // + // void getTagsForExistingNote(String noteTagsLocation) throws Exception { + // this.mockMvc.perform(get(noteTagsLocation)) + // .andExpect(status().isOk()).andExpect(jsonPath("_embedded.tags", hasSize(1))); + // } + // + // private String getLink(MvcResult result, String rel) + // throws UnsupportedEncodingException { + // return JsonPath.parse(result.getResponse().getContentAsString()).read("_links." + rel + ".href"); + // } } diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/persistence/model/User.java b/spring-security-custom-permission/src/main/java/org/baeldung/persistence/model/User.java index 86b81cdcee..112d502105 100644 --- a/spring-security-custom-permission/src/main/java/org/baeldung/persistence/model/User.java +++ b/spring-security-custom-permission/src/main/java/org/baeldung/persistence/model/User.java @@ -1,8 +1,5 @@ package org.baeldung.persistence.model; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; import java.util.Set; import javax.persistence.Column; @@ -16,14 +13,8 @@ import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; - @Entity -public class User implements UserDetails { - - private static final long serialVersionUID = 1L; +public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) @@ -57,7 +48,6 @@ public class User implements UserDetails { this.id = id; } - @Override public String getUsername() { return username; } @@ -66,7 +56,6 @@ public class User implements UserDetails { this.username = username; } - @Override public String getPassword() { return password; } @@ -93,37 +82,6 @@ public class User implements UserDetails { // - @Override - public Collection getAuthorities() { - final List authorities = new ArrayList(); - for (final Privilege privilege : this.getPrivileges()) { - authorities.add(new SimpleGrantedAuthority(privilege.getName())); - } - return authorities; - } - - @Override - public boolean isAccountNonExpired() { - return true; - } - - @Override - public boolean isAccountNonLocked() { - return true; - } - - @Override - public boolean isCredentialsNonExpired() { - return true; - } - - @Override - public boolean isEnabled() { - return true; - } - - // - @Override public String toString() { final StringBuilder builder = new StringBuilder(); diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionRoot.java b/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionRoot.java index a3f4644592..2d84536a14 100644 --- a/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionRoot.java +++ b/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionRoot.java @@ -16,7 +16,7 @@ public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot i // public boolean isMember(Long OrganizationId) { - final User user = (User) this.getPrincipal(); + final User user = ((MyUserPrincipal) this.getPrincipal()).getUser(); return user.getOrganization().getId().longValue() == OrganizationId.longValue(); } diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomPermissionEvaluator.java b/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomPermissionEvaluator.java index e81f9f8939..5d96673a8f 100644 --- a/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomPermissionEvaluator.java +++ b/spring-security-custom-permission/src/main/java/org/baeldung/security/CustomPermissionEvaluator.java @@ -10,17 +10,10 @@ public class CustomPermissionEvaluator implements PermissionEvaluator { @Override public boolean hasPermission(Authentication auth, Object targetDomainObject, Object permission) { - System.out.println(auth); if ((auth == null) || (targetDomainObject == null) || !(permission instanceof String)) { return false; } - String targetType = ""; - if (targetDomainObject instanceof String) { - targetType = targetDomainObject.toString().toUpperCase(); - } else { - targetType = targetDomainObject.getClass().getSimpleName().toUpperCase(); - System.out.println(targetType); - } + final String targetType = targetDomainObject.getClass().getSimpleName().toUpperCase(); return hasPrivilege(auth, targetType, permission.toString().toUpperCase()); } diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/security/MySecurityExpressionRoot.java b/spring-security-custom-permission/src/main/java/org/baeldung/security/MySecurityExpressionRoot.java index a09d166798..4d3561b325 100644 --- a/spring-security-custom-permission/src/main/java/org/baeldung/security/MySecurityExpressionRoot.java +++ b/spring-security-custom-permission/src/main/java/org/baeldung/security/MySecurityExpressionRoot.java @@ -47,6 +47,14 @@ public class MySecurityExpressionRoot implements MethodSecurityExpressionOperati throw new RuntimeException("method hasAuthority() not allowed"); } + // + public boolean isMember(Long OrganizationId) { + final User user = ((MyUserPrincipal) this.getPrincipal()).getUser(); + return user.getOrganization().getId().longValue() == OrganizationId.longValue(); + } + + // + @Override public final boolean hasAnyAuthority(String... authorities) { return hasAnyAuthorityName(null, authorities); @@ -168,14 +176,6 @@ public class MySecurityExpressionRoot implements MethodSecurityExpressionOperati return defaultRolePrefix + role; } - // - public boolean isMember(Long OrganizationId) { - final User user = (User) this.getPrincipal(); - return user.getOrganization().getId().longValue() == OrganizationId.longValue(); - } - - // - @Override public Object getFilterObject() { return this.filterObject; diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserDetailsService.java b/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserDetailsService.java index 19276a906e..685219728f 100644 --- a/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserDetailsService.java +++ b/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserDetailsService.java @@ -26,6 +26,6 @@ public class MyUserDetailsService implements UserDetailsService { if (user == null) { throw new UsernameNotFoundException(username); } - return user; + return new MyUserPrincipal(user); } } diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserPrincipal.java b/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserPrincipal.java new file mode 100644 index 0000000000..437bb02cdb --- /dev/null +++ b/spring-security-custom-permission/src/main/java/org/baeldung/security/MyUserPrincipal.java @@ -0,0 +1,72 @@ +package org.baeldung.security; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.baeldung.persistence.model.Privilege; +import org.baeldung.persistence.model.User; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +public class MyUserPrincipal implements UserDetails { + + private static final long serialVersionUID = 1L; + + private final User user; + + // + + public MyUserPrincipal(User user) { + this.user = user; + } + + // + + @Override + public String getUsername() { + return user.getUsername(); + } + + @Override + public String getPassword() { + return user.getPassword(); + } + + @Override + public Collection getAuthorities() { + final List authorities = new ArrayList(); + for (final Privilege privilege : user.getPrivileges()) { + authorities.add(new SimpleGrantedAuthority(privilege.getName())); + } + return authorities; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } + + // + + public User getUser() { + return user; + } + +} diff --git a/spring-security-custom-permission/src/main/java/org/baeldung/web/MainController.java b/spring-security-custom-permission/src/main/java/org/baeldung/web/MainController.java index 7e279907c6..4752f7bdd9 100644 --- a/spring-security-custom-permission/src/main/java/org/baeldung/web/MainController.java +++ b/spring-security-custom-permission/src/main/java/org/baeldung/web/MainController.java @@ -21,7 +21,8 @@ public class MainController { @Autowired private OrganizationRepository organizationRepository; - @PreAuthorize("hasPermission('Foo', 'read')") + // @PostAuthorize("hasPermission(returnObject, 'read')") + @PreAuthorize("hasPermission(#id, 'Foo', 'read')") @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}") @ResponseBody public Foo findById(@PathVariable final long id) { diff --git a/xmlunit2-tutorial/src/test/java/com/baeldung/xmlunit/XMLUnitTest.java b/xmlunit2-tutorial/src/test/java/com/baeldung/xmlunit/XMLUnitTest.java index d0e099e591..175250f47b 100644 --- a/xmlunit2-tutorial/src/test/java/com/baeldung/xmlunit/XMLUnitTest.java +++ b/xmlunit2-tutorial/src/test/java/com/baeldung/xmlunit/XMLUnitTest.java @@ -15,6 +15,7 @@ import static org.xmlunit.matchers.HasXPathMatcher.hasXPath; import java.io.File; import java.util.Iterator; +import org.junit.Ignore; import org.junit.Test; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; @@ -36,10 +37,10 @@ public class XMLUnitTest { public void givenWrongXml_whenValidateFailsAgainstXsd_thenCorrect() { Validator v = Validator.forLanguage(Languages.W3C_XML_SCHEMA_NS_URI); v.setSchemaSource(Input.fromStream( - new XMLUnitTest().getClass().getResourceAsStream( + XMLUnitTest.class.getResourceAsStream( "/students.xsd")).build()); ValidationResult r = v.validateInstance(Input.fromStream( - new XMLUnitTest().getClass().getResourceAsStream( + XMLUnitTest.class.getResourceAsStream( "/students_with_error.xml")).build()); assertFalse(r.isValid()); } @@ -48,10 +49,10 @@ public class XMLUnitTest { public void givenXmlWithErrors_whenReturnsValidationProblems_thenCorrect() { Validator v = Validator.forLanguage(Languages.W3C_XML_SCHEMA_NS_URI); v.setSchemaSource(Input.fromStream( - new XMLUnitTest().getClass().getResourceAsStream( + XMLUnitTest.class.getResourceAsStream( "/students.xsd")).build()); ValidationResult r = v.validateInstance(Input.fromStream( - new XMLUnitTest().getClass().getResourceAsStream( + XMLUnitTest.class.getResourceAsStream( "/students_with_error.xml")).build()); Iterator probs = r.getProblems().iterator(); int count = 0; @@ -66,10 +67,10 @@ public class XMLUnitTest { public void givenXml_whenValidatesAgainstXsd_thenCorrect() { Validator v = Validator.forLanguage(Languages.W3C_XML_SCHEMA_NS_URI); v.setSchemaSource(Input.fromStream( - new XMLUnitTest().getClass().getResourceAsStream( + XMLUnitTest.class.getResourceAsStream( "/students.xsd")).build()); ValidationResult r = v.validateInstance(Input.fromStream( - new XMLUnitTest().getClass().getResourceAsStream( + XMLUnitTest.class.getResourceAsStream( "/students.xml")).build()); Iterator probs = r.getProblems().iterator(); while (probs.hasNext()) { @@ -117,11 +118,27 @@ public class XMLUnitTest { @Test public void givenXmlSource_whenFailsToValidateInExistentXPath_thenCorrect() { ClassLoader classLoader = getClass().getClassLoader(); - assertThat(Input.fromFile(new File(classLoader.getResource( "teachers.xml").getFile())), not(hasXPath("//sujet"))); } + // NOTE: ignore as this test demonstrates that two XMLs that contain the same data + // will fail the isSimilarTo test. + @Test @Ignore + public void given2XMLS_whenSimilar_thenCorrect_fails() { + String controlXml = "3false"; + String testXml = "false3"; + assertThat(testXml, isSimilarTo(controlXml)); + } + + @Test + public void given2XMLS_whenSimilar_thenCorrect() { + String controlXml = "3false"; + String testXml = "false3"; + assertThat(testXml,isSimilarTo(controlXml).withNodeMatcher( + new DefaultNodeMatcher(ElementSelectors.byName))); + } + @Test public void given2XMLs_whenSimilarWithDiff_thenCorrect() throws Exception { String myControlXML = "3false"; @@ -160,6 +177,7 @@ public class XMLUnitTest { Diff myDiff = DiffBuilder.compare(control).withTest(test) .checkForSimilar().build(); + // assertFalse(myDiff.toString(), myDiff.hasDifferences()); assertTrue(myDiff.toString(), myDiff.hasDifferences()); } @@ -177,27 +195,23 @@ public class XMLUnitTest { @Test public void givenFileSourceAsObject_whenAbleToInput_thenCorrect() { ClassLoader classLoader = getClass().getClassLoader(); - assertThat(Input.from(new File(classLoader.getResource("test.xml") - .getFile())), isSimilarTo(Input.from(new File(classLoader - .getResource("control.xml").getFile())))); - + assertThat(Input.from(new File(classLoader.getResource("test.xml").getFile())), + isSimilarTo(Input.from(new File(classLoader.getResource("control.xml").getFile())))); } @Test public void givenStreamAsSource_whenAbleToInput_thenCorrect() { - assertThat(Input.fromStream(new XMLUnitTest().getClass() + assertThat(Input.fromStream(XMLUnitTest.class .getResourceAsStream("/test.xml")), - isSimilarTo(Input.fromStream(new XMLUnitTest().getClass() + isSimilarTo(Input.fromStream(XMLUnitTest.class .getResourceAsStream("/control.xml")))); } @Test public void givenStreamAsObject_whenAbleToInput_thenCorrect() { - assertThat(Input.from(new XMLUnitTest().getClass().getResourceAsStream( - "/test.xml")), isSimilarTo(Input.from(new XMLUnitTest() - .getClass().getResourceAsStream("/control.xml")))); - + assertThat(Input.from(XMLUnitTest.class.getResourceAsStream("/test.xml")), + isSimilarTo(Input.from(XMLUnitTest.class.getResourceAsStream("/control.xml")))); } @Test @@ -206,7 +220,6 @@ public class XMLUnitTest { Input.from("3false"), isSimilarTo(Input .from("3false"))); - } @Test @@ -216,7 +229,6 @@ public class XMLUnitTest { String controlPath = classLoader.getResource("control.xml").getPath(); assertThat(Input.fromFile(testPath), isSimilarTo(Input.fromFile(controlPath))); - } @Test