Merge pull request #1 from eugenp/master

update with eugenp
This commit is contained in:
ishwardas 2016-07-31 16:05:50 -05:00 committed by GitHub
commit 5a6f8d2f3e
132 changed files with 3406 additions and 774 deletions

View File

@ -0,0 +1,36 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>autovalue-tutorial</artifactId>
<version>1.0</version>
<name>AutoValue</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>7</source>
<target>7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.3</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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
+ "]";
}
}

View File

@ -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;
}
}

View File

@ -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");
}
}

59
dozer-tutorial/pom.xml Normal file
View File

@ -0,0 +1,59 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>dozer-tutorial</artifactId>
<version>1.0</version>
<name>Dozer</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>7</source>
<target>7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>net.sf.dozer</groupId>
<artifactId>dozer</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.3</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -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;
}
}

View File

@ -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 + "]";
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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 + "]";
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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 + "]";
}
}

View File

@ -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;
}
}

View File

@ -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 + "]";
}
}

View File

@ -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<String> 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<String> 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<String> 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<String> 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'&&timestampTest.charAt(19)=='Z');
}
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net
http://dozer.sourceforge.net/schema/beanmapping.xsd">
<configuration>
<custom-converters>
<converter type="com.baeldung.dozer.MyCustomConvertor">
<class-a>com.baeldung.dozer.Personne3</class-a>
<class-b>com.baeldung.dozer.Person3</class-b>
</converter>
</custom-converters>
</configuration>
</mappings>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net
http://dozer.sourceforge.net/schema/beanmapping.xsd">
<mapping>
<class-a>com.baeldung.dozer.Personne</class-a>
<class-b>com.baeldung.dozer.Person</class-b>
<field>
<a>nom</a>
<b>name</b>
</field>
<field>
<a>surnom</a>
<b>nickname</b>
</field>
</mapping>
</mappings>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozer.sourceforge.net
http://dozer.sourceforge.net/schema/beanmapping.xsd">
<mapping wildcard="false">
<class-a>com.baeldung.dozer.Personne</class-a>
<class-b>com.baeldung.dozer.Person</class-b>
<field>
<a>nom</a>
<b>name</b>
</field>
<field>
<a>surnom</a>
<b>nickname</b>
</field>
</mapping>
</mappings>

View File

@ -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.";
}
}

50
immutables/pom.xml Normal file
View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>immutables</artifactId>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.immutables</groupId>
<artifactId>value</artifactId>
<version>2.2.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.5.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mutabilitydetector</groupId>
<artifactId>MutabilityDetector</artifactId>
<version>0.9.5</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,9 @@
package com.baeldung.immutable;
import org.immutables.value.Value;
@Value.Immutable
public interface Address {
String getStreetName();
Integer getNumber();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -7,18 +7,26 @@ import org.slf4j.LoggerFactory;
import com.baeldung.jackson.objectmapper.dto.Car; import com.baeldung.jackson.objectmapper.dto.Car;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
public class CustomCarDeserializer extends JsonDeserializer<Car> { public class CustomCarDeserializer extends StdDeserializer<Car> {
private static final long serialVersionUID = -5918629454846356161L;
private final Logger Logger = LoggerFactory.getLogger(getClass()); private final Logger Logger = LoggerFactory.getLogger(getClass());
public CustomCarDeserializer() { public CustomCarDeserializer() {
this(null);
} }
public CustomCarDeserializer(final Class<?> vc) {
super(vc);
}
@Override @Override
public Car deserialize(final JsonParser parser, final DeserializationContext deserializer) throws IOException { public Car deserialize(final JsonParser parser, final DeserializationContext deserializer) throws IOException {
final Car car = new Car(); final Car car = new Car();

View File

@ -1,16 +1,25 @@
package com.baeldung.jackson.objectmapper; package com.baeldung.jackson.objectmapper;
import java.io.IOException;
import com.baeldung.jackson.objectmapper.dto.Car; import com.baeldung.jackson.objectmapper.dto.Car;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException; public class CustomCarSerializer extends StdSerializer<Car>
public class CustomCarSerializer extends JsonSerializer<Car>
{ {
public CustomCarSerializer() { }
private static final long serialVersionUID = 1396140685442227917L;
public CustomCarSerializer() {
this(null);
}
public CustomCarSerializer(final Class<Car> t) {
super(t);
}
@Override @Override
public void serialize(final Car car, final JsonGenerator jsonGenerator, final SerializerProvider serializer) throws IOException, JsonProcessingException public void serialize(final Car car, final JsonGenerator jsonGenerator, final SerializerProvider serializer) throws IOException, JsonProcessingException

View File

@ -6,3 +6,4 @@
### Relevant Articles: ### Relevant Articles:
- [JMockit 101](http://www.baeldung.com/jmockit-101) - [JMockit 101](http://www.baeldung.com/jmockit-101)
- [A Guide to JMockit Expectations](http://www.baeldung.com/jmockit-expectations) - [A Guide to JMockit Expectations](http://www.baeldung.com/jmockit-expectations)
- [JMockit Advanced Topics](http://www.baeldung.com/jmockit-advanced-topics)

View File

@ -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{}
}

View File

@ -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);
}
}

View File

@ -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<MultiMock extends List<String> & Comparable<List<String>>> {
@Tested
private AdvancedCollaborator mock;
@Mocked
private MultiMock multiMock;
@Test
public void testToMockUpPrivateMethod() {
new MockUp<AdvancedCollaborator>() {
@Mock
private String privateMethod() {
return "mocked: ";
}
};
String res = mock.methodThatCallsPrivateMethod(1);
assertEquals("mocked: 1", res);
}
@Test
public void testToMockUpDifficultConstructor() throws Exception {
new MockUp<AdvancedCollaborator>() {
@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<String>) any); result = 0;
}
};
assertEquals("foo", multiMock.get(5));
assertEquals(0, multiMock.compareTo(new ArrayList<>()));
}
@Test
@SuppressWarnings("unchecked")
public <M extends List<String> & Comparable<List<String>>> void testMultipleInterfacesOneMethod(@Mocked M mock) {
new Expectations() {
{
mock.get(5); result = "foo";
mock.compareTo((List<String>) any);
result = 0; }
};
assertEquals("foo", mock.get(5));
assertEquals(0, mock.compareTo(new ArrayList<>()));
}
}

View File

@ -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);
}
}

View File

@ -31,6 +31,7 @@
<module>guava19</module> <module>guava19</module>
<module>handling-spring-static-resources</module> <module>handling-spring-static-resources</module>
<module>httpclient</module> <module>httpclient</module>
<module>immutables</module>
<module>jackson</module> <module>jackson</module>
<module>javaxval</module> <module>javaxval</module>
<module>jjwt</module> <module>jjwt</module>
@ -55,7 +56,7 @@
<module>spring-autowire</module> <module>spring-autowire</module>
<module>spring-batch</module> <module>spring-batch</module>
<module>spring-boot</module> <module>spring-boot</module>
<module>spring-controller</module> <module>spring-cucumber</module>
<module>spring-data-cassandra</module> <module>spring-data-cassandra</module>
<module>spring-data-couchbase-2</module> <module>spring-data-couchbase-2</module>
<module>spring-data-couchbase-2b</module> <module>spring-data-couchbase-2b</module>

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/webapp"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
<attributes>
<attribute name="hide" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
<classpathentry kind="output" path=""/>
</classpath>

View File

@ -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

View File

@ -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

View File

@ -1,4 +0,0 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@ -1,2 +0,0 @@
eclipse.preferences.version=1
org.eclipse.m2e.wtp.enabledProjectSpecificPrefs=false

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="spring-all">
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<property name="context-root" value="spring-all"/>
<property name="java-output-path" value="/spring-all/target/classes"/>
</wb-module>
</project-modules>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<installed facet="wst.jsdt.web" version="1.0"/>
<installed facet="java" version="1.8"/>
<installed facet="jst.web" version="3.1"/>
</faceted-project>

View File

@ -1 +0,0 @@
org.eclipse.wst.jsdt.launching.baseBrowserLibrary

View File

@ -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

View File

@ -1,2 +0,0 @@
eclipse.preferences.version=1
org.eclipse.wst.ws.service.policy.projectEnabled=false

View File

@ -14,6 +14,10 @@
</parent> </parent>
<dependencies> <dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Spring --> <!-- Spring -->
@ -41,11 +45,6 @@
<artifactId>spring-aspects</artifactId> <artifactId>spring-aspects</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<!-- persistence --> <!-- persistence -->
<dependency> <dependency>
@ -88,6 +87,14 @@
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<!-- Akka -->
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.11</artifactId>
<version>2.4.8</version>
</dependency>
<!-- util --> <!-- util -->
<dependency> <dependency>

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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<? extends Actor> actorClass() {
return (Class<? extends Actor>) applicationContext.getType(beanActorName);
}
}

View File

@ -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<SpringExtension.SpringExt> {
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);
}
}
}

View File

@ -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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;

View File

@ -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.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;

View File

@ -2,7 +2,7 @@
/** /**
* @author Prashant Dutta * @author Prashant Dutta
*/ */
package com.baeldung.controller; package org.baeldung.controller.controller;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;

View File

@ -1,4 +1,4 @@
package com.baeldung.student; package org.baeldung.controller.student;
public class Student { public class Student {
private String name; private String name;

View File

@ -10,7 +10,7 @@
http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="com.baeldung.controller" /> <context:component-scan base-package="org.baeldung.controller.controller" />
<mvc:annotation-driven /> <mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

View File

@ -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<Object> result = ask(greeter, new Greet("John"), timeout);
Assert.assertEquals("Hello, John", Await.result(result, duration));
}
@After
public void tearDown() {
system.shutdown();
system.awaitTermination();
}
}

View File

@ -1,4 +1,4 @@
package com.baeldung.test; package org.baeldung.controller;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; 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.context.WebApplicationContext;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import com.baeldung.student.Student; import org.baeldung.controller.student.Student;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)

View File

@ -1,56 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>spring-controller</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
</dependencies>
</project>

89
spring-cucumber/pom.xml Normal file
View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>spring-cucumber</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-cucumber</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<cucumber.java.version>1.2.4</cucumber.java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-core</artifactId>
<version>${cucumber.java.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.java.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber.java.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-spring</artifactId>
<version>${cucumber.java.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-io -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -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";
}
}

View File

@ -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);
}
}

View File

@ -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";
}
}

View File

@ -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{
}

View File

@ -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<String,String> requestHeaders;
private String body;
public HeaderSettingRequestCallback(final Map<String, String> 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<String,String> entry : requestHeaders.entrySet() ){
clientHeaders.add(entry.getKey(),entry.getValue());
}
if( null != body ){
request.getBody().write( body.getBytes() );
}
}
}

View File

@ -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");
}
}

View File

@ -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;
}
}

View File

@ -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<String,String> 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<ResponseResults>(){
@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<String,String> 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<ResponseResults>(){
@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);
}
}
}

View File

@ -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)) ;
}
}

View File

@ -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

View File

@ -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

View File

@ -130,6 +130,32 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.12.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>10.12.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbynet</artifactId>
<version>10.12.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbytools</artifactId>
<version>10.12.1.1</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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());
}
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -128,6 +128,9 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId> <artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version> <version>${maven-war-plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin> </plugin>
<plugin> <plugin>

View File

@ -1,7 +1,7 @@
package com.baeldung.mvc.velocity.controller; package com.baeldung.mvc.velocity.controller;
import com.baeldung.mvc.velocity.domain.Tutorial; 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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
@ -14,21 +14,29 @@ import java.util.List;
@RequestMapping("/") @RequestMapping("/")
public class MainController { public class MainController {
private final TutorialsService tutService;
@Autowired @Autowired
public MainController(TutorialsService tutService) { private ITutorialsService tutService;
this.tutService = 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) { public String listTutorialsPage(Model model) {
List<Tutorial> list = tutService.listTutorials(); List<Tutorial> list = tutService.listTutorials();
model.addAttribute("tutorials", list); model.addAttribute("tutorials", list);
return "index"; return "list";
} }
public TutorialsService getTutService() { public ITutorialsService getTutService() {
return tutService; return tutService;
} }
public void setTutService(ITutorialsService tutService) {
this.tutService = tutService;
}
} }

View File

@ -14,21 +14,20 @@ public class Tutorial {
this.author = author; this.author = author;
} }
public Integer getTutId() { public Integer getTutId() {
return tutId; return tutId;
} }
public String getTitle() { public String getTitle() {
return title; return title;
} }
public String getDescription() { public String getDescription() {
return description; return description;
} }
public String getAuthor() {
return author;
}
public String getAuthor() {
return author;
}
} }

View File

@ -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<String> 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");
}
}
}

View File

@ -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;
}
}

View File

@ -1,6 +1,6 @@
<html> <html>
<head> <head>
<title>Spring & Velocity</title> <title>Spring with Velocity</title>
</head> </head>
<body> <body>
<div> <div>

View File

@ -1,19 +1,4 @@
<h1>Index</h1> <h1>Index</h1>
<h2>Tutorials list</h2> <h2>Welcome page</h2>
<table border="1"> This is just the welcome page
<tr>
<th>Tutorial Id</th>
<th>Tutorial Title</th>
<th>Tutorial Description</th>
<th>Tutorial Author</th>
</tr>
#foreach($tut in $tutorials)
<tr>
<td>$tut.tutId</td>
<td>$tut.title</td>
<td>$tut.description</td>
<td>$tut.author</td>
</tr>
#end
</table>

View File

@ -0,0 +1,19 @@
<h1>Index</h1>
<h2>Tutorials list</h2>
<table border="1">
<tr>
<th>Tutorial Id</th>
<th>Tutorial Title</th>
<th>Tutorial Description</th>
<th>Tutorial Author</th>
</tr>
#foreach($tut in $tutorials)
<tr>
<td id="tutId_$foreach.count">$tut.tutId</td>
<td id="title_$foreach.count">$tut.title</td>
<td id="desc_$foreach.count">$tut.description</td>
<td id="auth_$foreach.count">$tut.author</td>
</tr>
#end
</table>

Some files were not shown because too many files have changed in this diff Show More