From aacc25a75204f69e4876a8a901d313671e3ac8a8 Mon Sep 17 00:00:00 2001 From: Sunil Mogadati Date: Tue, 10 Jan 2017 00:51:36 -0700 Subject: [PATCH 01/14] BAEL-245: Add more tests to align with previous enum example and prevent build fail (#981) * Add NDC and JBoss Logging to the demo application * NDC for Log4j, Log4j2 and JBoss Logging * Simplify NDC example by making it a single operation instead of two * Make NDC example as RestController, Use JBoss Logging only as a logging bridge * Fix merge conflicts in pull request - log-mdc pom.xml updated * BAEL-445 Update to Spring security SpEL example * BAEL-445: Change tabs to spaces in the updated code * BAEL-245: Add Enum Serialization exmaple * BAEL-245: Remove the folder jackson/src/test/java/com/baeldung/jackson/dtos/withEnum as the example is not used anymore * Add more enum serialization examples to align with previous example and prevent build fail --- .../dtos/withEnum/DistanceEnumSimple.java | 26 ++++++++ .../withEnum/DistanceEnumWithJsonFormat.java | 29 +++++++++ .../dtos/withEnum/DistanceEnumWithValue.java | 29 +++++++++ .../dtos/withEnum/MyDtoWithEnumCustom.java | 59 +++++++++++++++++++ .../withEnum/MyDtoWithEnumJsonFormat.java | 57 ++++++++++++++++++ .../jackson/test/JacksonAnnotationTest.java | 47 ++++++++++----- .../JacksonSerializationEnumsUnitTest.java | 42 ++++++------- 7 files changed, 249 insertions(+), 40 deletions(-) create mode 100644 jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumSimple.java create mode 100644 jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithJsonFormat.java create mode 100644 jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithValue.java create mode 100644 jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/MyDtoWithEnumCustom.java create mode 100644 jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/MyDtoWithEnumJsonFormat.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumSimple.java b/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumSimple.java new file mode 100644 index 0000000000..1118fb349a --- /dev/null +++ b/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumSimple.java @@ -0,0 +1,26 @@ +package com.baeldung.jackson.dtos.withEnum; + +public enum DistanceEnumSimple { + KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001); + + private String unit; + private final double meters; + + private DistanceEnumSimple(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + public double getMeters() { + return meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + +} \ No newline at end of file diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithJsonFormat.java b/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithJsonFormat.java new file mode 100644 index 0000000000..7dc6bb559b --- /dev/null +++ b/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithJsonFormat.java @@ -0,0 +1,29 @@ +package com.baeldung.jackson.dtos.withEnum; + +import com.fasterxml.jackson.annotation.JsonFormat; + +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum DistanceEnumWithJsonFormat { + KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001); + + private String unit; + private final double meters; + + private DistanceEnumWithJsonFormat(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + public double getMeters() { + return meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + +} \ No newline at end of file diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithValue.java b/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithValue.java new file mode 100644 index 0000000000..69c476d8a5 --- /dev/null +++ b/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithValue.java @@ -0,0 +1,29 @@ +package com.baeldung.jackson.dtos.withEnum; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum DistanceEnumWithValue { + KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001); + + private String unit; + private final double meters; + + private DistanceEnumWithValue(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + @JsonValue + public double getMeters() { + return meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + +} \ No newline at end of file diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/MyDtoWithEnumCustom.java b/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/MyDtoWithEnumCustom.java new file mode 100644 index 0000000000..bf9b7db395 --- /dev/null +++ b/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/MyDtoWithEnumCustom.java @@ -0,0 +1,59 @@ +package com.baeldung.jackson.dtos.withEnum; + +import com.baeldung.jackson.enums.Distance; + +public class MyDtoWithEnumCustom { + + private String stringValue; + private int intValue; + private boolean booleanValue; + private Distance type; + + public MyDtoWithEnumCustom() { + super(); + } + + public MyDtoWithEnumCustom(final String stringValue, final int intValue, final boolean booleanValue, final Distance type) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + this.type = type; + } + + // API + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(final String stringValue) { + this.stringValue = stringValue; + } + + public int getIntValue() { + return intValue; + } + + public void setIntValue(final int intValue) { + this.intValue = intValue; + } + + public boolean isBooleanValue() { + return booleanValue; + } + + public void setBooleanValue(final boolean booleanValue) { + this.booleanValue = booleanValue; + } + + public Distance getType() { + return type; + } + + public void setType(final Distance type) { + this.type = type; + } + +} diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/MyDtoWithEnumJsonFormat.java b/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/MyDtoWithEnumJsonFormat.java new file mode 100644 index 0000000000..8e2f1b835f --- /dev/null +++ b/jackson/src/test/java/com/baeldung/jackson/dtos/withEnum/MyDtoWithEnumJsonFormat.java @@ -0,0 +1,57 @@ +package com.baeldung.jackson.dtos.withEnum; + +public class MyDtoWithEnumJsonFormat { + + private String stringValue; + private int intValue; + private boolean booleanValue; + private DistanceEnumWithJsonFormat distanceType; + + public MyDtoWithEnumJsonFormat() { + super(); + } + + public MyDtoWithEnumJsonFormat(final String stringValue, final int intValue, final boolean booleanValue, final DistanceEnumWithJsonFormat type) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + this.distanceType = type; + } + + // API + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(final String stringValue) { + this.stringValue = stringValue; + } + + public int getIntValue() { + return intValue; + } + + public void setIntValue(final int intValue) { + this.intValue = intValue; + } + + public boolean isBooleanValue() { + return booleanValue; + } + + public void setBooleanValue(final boolean booleanValue) { + this.booleanValue = booleanValue; + } + + public DistanceEnumWithJsonFormat getDistanceType() { + return distanceType; + } + + public void setDistanceType(final DistanceEnumWithJsonFormat type) { + this.distanceType = type; + } + +} diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationTest.java b/jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationTest.java index f2464d4251..9351b929d3 100644 --- a/jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationTest.java +++ b/jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationTest.java @@ -1,6 +1,32 @@ package com.baeldung.jackson.test; -import com.baeldung.jackson.annotation.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +import org.junit.Test; + +import com.baeldung.jackson.annotation.BeanWithCreator; +import com.baeldung.jackson.annotation.BeanWithCustomAnnotation; +import com.baeldung.jackson.annotation.BeanWithFilter; +import com.baeldung.jackson.annotation.BeanWithGetter; +import com.baeldung.jackson.annotation.BeanWithIgnore; +import com.baeldung.jackson.annotation.BeanWithInject; +import com.baeldung.jackson.annotation.ExtendableBean; +import com.baeldung.jackson.annotation.MyBean; +import com.baeldung.jackson.annotation.PrivateBean; +import com.baeldung.jackson.annotation.RawBean; +import com.baeldung.jackson.annotation.UnwrappedUser; +import com.baeldung.jackson.annotation.UserWithIgnoreType; +import com.baeldung.jackson.annotation.Zoo; import com.baeldung.jackson.bidirection.ItemWithIdentity; import com.baeldung.jackson.bidirection.ItemWithRef; import com.baeldung.jackson.bidirection.UserWithIdentity; @@ -8,7 +34,7 @@ import com.baeldung.jackson.bidirection.UserWithRef; import com.baeldung.jackson.date.EventWithFormat; import com.baeldung.jackson.date.EventWithSerializer; import com.baeldung.jackson.dtos.MyMixInForIgnoreType; -import com.baeldung.jackson.dtos.withEnum.TypeEnumWithValue; +import com.baeldung.jackson.dtos.withEnum.DistanceEnumWithValue; import com.baeldung.jackson.exception.UserWithRoot; import com.baeldung.jackson.jsonview.Item; import com.baeldung.jackson.jsonview.Views; @@ -20,17 +46,6 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.ser.FilterProvider; import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; -import org.junit.Test; - -import java.io.IOException; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.TimeZone; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; public class JacksonAnnotationTest { @@ -85,10 +100,10 @@ public class JacksonAnnotationTest { } @Test - public void whenSerializingUsingJsonValue_thenCorrect() throws JsonProcessingException { - final String enumAsString = new ObjectMapper().writeValueAsString(TypeEnumWithValue.TYPE1); + public void whenSerializingUsingJsonValue_thenCorrect() throws IOException { + final String enumAsString = new ObjectMapper().writeValueAsString(DistanceEnumWithValue.MILE); - assertThat(enumAsString, is("\"Type A\"")); + assertThat(enumAsString, is("1609.34")); } @Test diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationEnumsUnitTest.java b/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationEnumsUnitTest.java index 78c6316aa6..0f57d26d8b 100644 --- a/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationEnumsUnitTest.java +++ b/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationEnumsUnitTest.java @@ -6,14 +6,14 @@ import static org.junit.Assert.assertThat; import java.io.IOException; -import com.baeldung.jackson.dtos.withEnum.MyDtoWithEnum; -import com.baeldung.jackson.dtos.withEnum.TypeEnum; -import com.baeldung.jackson.dtos.withEnum.TypeEnumSimple; -import com.baeldung.jackson.dtos.withEnum.TypeEnumWithValue; -import com.baeldung.jackson.dtos.withEnum.MyDtoWithEnumCustom; -import com.baeldung.jackson.dtos.withEnum.TypeEnumWithCustomSerializer; import org.junit.Test; +import com.baeldung.jackson.dtos.withEnum.DistanceEnumSimple; +import com.baeldung.jackson.dtos.withEnum.DistanceEnumWithJsonFormat; +import com.baeldung.jackson.dtos.withEnum.DistanceEnumWithValue; +import com.baeldung.jackson.dtos.withEnum.MyDtoWithEnumCustom; +import com.baeldung.jackson.dtos.withEnum.MyDtoWithEnumJsonFormat; +import com.baeldung.jackson.enums.Distance; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -24,10 +24,9 @@ public class JacksonSerializationEnumsUnitTest { @Test public final void whenSerializingASimpleEnum_thenCorrect() throws JsonParseException, IOException { final ObjectMapper mapper = new ObjectMapper(); - final String enumAsString = mapper.writeValueAsString(TypeEnumSimple.TYPE1); - System.out.println(enumAsString); + final String enumAsString = mapper.writeValueAsString(DistanceEnumSimple.MILE); - assertThat(enumAsString, containsString("TYPE1")); + assertThat(enumAsString, containsString("MILE")); } // tests - enum with main value @@ -35,10 +34,9 @@ public class JacksonSerializationEnumsUnitTest { @Test public final void whenSerializingAEnumWithValue_thenCorrect() throws JsonParseException, IOException { final ObjectMapper mapper = new ObjectMapper(); - final String enumAsString = mapper.writeValueAsString(TypeEnumWithValue.TYPE1); - System.out.println(enumAsString); + final String enumAsString = mapper.writeValueAsString(DistanceEnumWithValue.MILE); - assertThat(enumAsString, is("\"Type A\"")); + assertThat(enumAsString, is("1609.34")); } // tests - enum @@ -46,28 +44,25 @@ public class JacksonSerializationEnumsUnitTest { @Test public final void whenSerializingAnEnum_thenCorrect() throws JsonParseException, IOException { final ObjectMapper mapper = new ObjectMapper(); - final String enumAsString = mapper.writeValueAsString(TypeEnum.TYPE1); + final String enumAsString = mapper.writeValueAsString(DistanceEnumWithJsonFormat.MILE); - System.out.println(enumAsString); - assertThat(enumAsString, containsString("\"name\":\"Type A\"")); + assertThat(enumAsString, containsString("\"meters\":1609.34")); } @Test public final void whenSerializingEntityWithEnum_thenCorrect() throws JsonParseException, IOException { final ObjectMapper mapper = new ObjectMapper(); - final String enumAsString = mapper.writeValueAsString(new MyDtoWithEnum("a", 1, true, TypeEnum.TYPE1)); + final String enumAsString = mapper.writeValueAsString(new MyDtoWithEnumJsonFormat("a", 1, true, DistanceEnumWithJsonFormat.MILE)); - System.out.println(enumAsString); - assertThat(enumAsString, containsString("\"name\":\"Type A\"")); + assertThat(enumAsString, containsString("\"meters\":1609.34")); } @Test public final void whenSerializingArrayOfEnums_thenCorrect() throws JsonParseException, IOException { final ObjectMapper mapper = new ObjectMapper(); - final String json = mapper.writeValueAsString(new TypeEnum[] { TypeEnum.TYPE1, TypeEnum.TYPE2 }); + final String json = mapper.writeValueAsString(new DistanceEnumWithJsonFormat[] { DistanceEnumWithJsonFormat.MILE, DistanceEnumWithJsonFormat.KILOMETER }); - System.out.println(json); - assertThat(json, containsString("\"name\":\"Type A\"")); + assertThat(json, containsString("\"meters\":1609.34")); } // tests - enum with custom serializer @@ -75,10 +70,9 @@ public class JacksonSerializationEnumsUnitTest { @Test public final void givenCustomSerializer_whenSerializingEntityWithEnum_thenCorrect() throws JsonParseException, IOException { final ObjectMapper mapper = new ObjectMapper(); - final String enumAsString = mapper.writeValueAsString(new MyDtoWithEnumCustom("a", 1, true, TypeEnumWithCustomSerializer.TYPE1)); + final String enumAsString = mapper.writeValueAsString(new MyDtoWithEnumCustom("a", 1, true, Distance.MILE)); - System.out.println(enumAsString); - assertThat(enumAsString, containsString("\"name\":\"Type A\"")); + assertThat(enumAsString, containsString("\"meters\":1609.34")); } } From 1423907bf0dc51d1dccf578c4d12a3aab048620b Mon Sep 17 00:00:00 2001 From: eugenp Date: Tue, 10 Jan 2017 16:13:20 +0200 Subject: [PATCH 02/14] cleanup work --- spring-data-mongodb/pom.xml | 9 +++++---- .../{GridFSIntegrationTest.java => GridFSLiveTest.java} | 2 +- ...ryIntegrationTest.java => DocumentQueryLiveTest.java} | 2 +- ...egrationTest.java => MongoTemplateQueryLiveTest.java} | 2 +- ...eQueryIntegrationTest.java => BaseQueryLiveTest.java} | 2 +- ...SLQueryIntegrationTest.java => DSLQueryLiveTest.java} | 2 +- ...NQueryIntegrationTest.java => JSONQueryLiveTest.java} | 2 +- ...odsIntegrationTest.java => QueryMethodsLiveTest.java} | 2 +- ...yIntegrationTest.java => UserRepositoryLiveTest.java} | 2 +- spring-mvc-java/pom.xml | 4 ++-- 10 files changed, 15 insertions(+), 14 deletions(-) rename spring-data-mongodb/src/test/java/org/baeldung/gridfs/{GridFSIntegrationTest.java => GridFSLiveTest.java} (99%) rename spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/{DocumentQueryIntegrationTest.java => DocumentQueryLiveTest.java} (99%) rename spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/{MongoTemplateQueryIntegrationTest.java => MongoTemplateQueryLiveTest.java} (99%) rename spring-data-mongodb/src/test/java/org/baeldung/repository/{BaseQueryIntegrationTest.java => BaseQueryLiveTest.java} (94%) rename spring-data-mongodb/src/test/java/org/baeldung/repository/{DSLQueryIntegrationTest.java => DSLQueryLiveTest.java} (97%) rename spring-data-mongodb/src/test/java/org/baeldung/repository/{JSONQueryIntegrationTest.java => JSONQueryLiveTest.java} (97%) rename spring-data-mongodb/src/test/java/org/baeldung/repository/{QueryMethodsIntegrationTest.java => QueryMethodsLiveTest.java} (97%) rename spring-data-mongodb/src/test/java/org/baeldung/repository/{UserRepositoryIntegrationTest.java => UserRepositoryLiveTest.java} (99%) diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index 7d7c9cd590..726fcf5f25 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 com.baeldung @@ -160,10 +161,10 @@ - + UTF-8 - + 4.3.4.RELEASE 1.8.6.RELEASE @@ -177,7 +178,7 @@ 1.7.21 1.1.7 3.6.0 - 2.19.1 + 2.19.1 diff --git a/spring-data-mongodb/src/test/java/org/baeldung/gridfs/GridFSIntegrationTest.java b/spring-data-mongodb/src/test/java/org/baeldung/gridfs/GridFSLiveTest.java similarity index 99% rename from spring-data-mongodb/src/test/java/org/baeldung/gridfs/GridFSIntegrationTest.java rename to spring-data-mongodb/src/test/java/org/baeldung/gridfs/GridFSLiveTest.java index bb4b268ca7..3853a406fb 100644 --- a/spring-data-mongodb/src/test/java/org/baeldung/gridfs/GridFSIntegrationTest.java +++ b/spring-data-mongodb/src/test/java/org/baeldung/gridfs/GridFSLiveTest.java @@ -33,7 +33,7 @@ import com.mongodb.gridfs.GridFSDBFile; @ContextConfiguration("file:src/main/resources/mongoConfig.xml") @RunWith(SpringJUnit4ClassRunner.class) -public class GridFSIntegrationTest { +public class GridFSLiveTest { private final Logger logger = LoggerFactory.getLogger(getClass()); diff --git a/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/DocumentQueryIntegrationTest.java b/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/DocumentQueryLiveTest.java similarity index 99% rename from spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/DocumentQueryIntegrationTest.java rename to spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/DocumentQueryLiveTest.java index cf46c6ed6e..df3ebcb2d2 100644 --- a/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/DocumentQueryIntegrationTest.java +++ b/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/DocumentQueryLiveTest.java @@ -25,7 +25,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) -public class DocumentQueryIntegrationTest { +public class DocumentQueryLiveTest { @Autowired private MongoTemplate mongoTemplate; diff --git a/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateQueryIntegrationTest.java b/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateQueryLiveTest.java similarity index 99% rename from spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateQueryIntegrationTest.java rename to spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateQueryLiveTest.java index 1701b9ac5a..76162c6096 100644 --- a/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateQueryIntegrationTest.java +++ b/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateQueryLiveTest.java @@ -28,7 +28,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) -public class MongoTemplateQueryIntegrationTest { +public class MongoTemplateQueryLiveTest { @Autowired private MongoTemplate mongoTemplate; diff --git a/spring-data-mongodb/src/test/java/org/baeldung/repository/BaseQueryIntegrationTest.java b/spring-data-mongodb/src/test/java/org/baeldung/repository/BaseQueryLiveTest.java similarity index 94% rename from spring-data-mongodb/src/test/java/org/baeldung/repository/BaseQueryIntegrationTest.java rename to spring-data-mongodb/src/test/java/org/baeldung/repository/BaseQueryLiveTest.java index 8572cc858e..afd7259c6c 100644 --- a/spring-data-mongodb/src/test/java/org/baeldung/repository/BaseQueryIntegrationTest.java +++ b/spring-data-mongodb/src/test/java/org/baeldung/repository/BaseQueryLiveTest.java @@ -7,7 +7,7 @@ import org.junit.Before; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoOperations; -public class BaseQueryIntegrationTest { +public class BaseQueryLiveTest { @Autowired protected UserRepository userRepository; diff --git a/spring-data-mongodb/src/test/java/org/baeldung/repository/DSLQueryIntegrationTest.java b/spring-data-mongodb/src/test/java/org/baeldung/repository/DSLQueryLiveTest.java similarity index 97% rename from spring-data-mongodb/src/test/java/org/baeldung/repository/DSLQueryIntegrationTest.java rename to spring-data-mongodb/src/test/java/org/baeldung/repository/DSLQueryLiveTest.java index ca8d46a97a..03fd38c796 100644 --- a/spring-data-mongodb/src/test/java/org/baeldung/repository/DSLQueryIntegrationTest.java +++ b/spring-data-mongodb/src/test/java/org/baeldung/repository/DSLQueryLiveTest.java @@ -17,7 +17,7 @@ import com.mysema.query.types.Predicate; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) -public class DSLQueryIntegrationTest extends BaseQueryIntegrationTest { +public class DSLQueryLiveTest extends BaseQueryLiveTest { @Test public void givenUsersExist_whenFindingUsersByName_thenUserAreFound() { diff --git a/spring-data-mongodb/src/test/java/org/baeldung/repository/JSONQueryIntegrationTest.java b/spring-data-mongodb/src/test/java/org/baeldung/repository/JSONQueryLiveTest.java similarity index 97% rename from spring-data-mongodb/src/test/java/org/baeldung/repository/JSONQueryIntegrationTest.java rename to spring-data-mongodb/src/test/java/org/baeldung/repository/JSONQueryLiveTest.java index ed88429792..9464a4eb52 100644 --- a/spring-data-mongodb/src/test/java/org/baeldung/repository/JSONQueryIntegrationTest.java +++ b/spring-data-mongodb/src/test/java/org/baeldung/repository/JSONQueryLiveTest.java @@ -14,7 +14,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) -public class JSONQueryIntegrationTest extends BaseQueryIntegrationTest { +public class JSONQueryLiveTest extends BaseQueryLiveTest { @Test public void givenUsersExist_whenFindingUsersByName_thenUsersAreFound() { diff --git a/spring-data-mongodb/src/test/java/org/baeldung/repository/QueryMethodsIntegrationTest.java b/spring-data-mongodb/src/test/java/org/baeldung/repository/QueryMethodsLiveTest.java similarity index 97% rename from spring-data-mongodb/src/test/java/org/baeldung/repository/QueryMethodsIntegrationTest.java rename to spring-data-mongodb/src/test/java/org/baeldung/repository/QueryMethodsLiveTest.java index f7c35c8de2..5705c119b8 100644 --- a/spring-data-mongodb/src/test/java/org/baeldung/repository/QueryMethodsIntegrationTest.java +++ b/spring-data-mongodb/src/test/java/org/baeldung/repository/QueryMethodsLiveTest.java @@ -14,7 +14,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) -public class QueryMethodsIntegrationTest extends BaseQueryIntegrationTest { +public class QueryMethodsLiveTest extends BaseQueryLiveTest { @Test public void givenUsersExist_whenFindingUsersByName_thenUsersAreFound() { diff --git a/spring-data-mongodb/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java b/spring-data-mongodb/src/test/java/org/baeldung/repository/UserRepositoryLiveTest.java similarity index 99% rename from spring-data-mongodb/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java rename to spring-data-mongodb/src/test/java/org/baeldung/repository/UserRepositoryLiveTest.java index 53cadc09bc..1543b847ba 100644 --- a/spring-data-mongodb/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java +++ b/spring-data-mongodb/src/test/java/org/baeldung/repository/UserRepositoryLiveTest.java @@ -24,7 +24,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) -public class UserRepositoryIntegrationTest { +public class UserRepositoryLiveTest { @Autowired private UserRepository userRepository; diff --git a/spring-mvc-java/pom.xml b/spring-mvc-java/pom.xml index 38443f2022..7d0cc24d41 100644 --- a/spring-mvc-java/pom.xml +++ b/spring-mvc-java/pom.xml @@ -323,9 +323,9 @@ - + - + 4.3.4.RELEASE From 6e9b667aef2a2e0bb1d0ecc0b4fbedbaaf44aa2b Mon Sep 17 00:00:00 2001 From: KevinGilmore Date: Tue, 10 Jan 2017 12:34:18 -0600 Subject: [PATCH 03/14] Update README.md --- spring-thymeleaf/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-thymeleaf/README.md b/spring-thymeleaf/README.md index 6b12bb676c..67bdddaf64 100644 --- a/spring-thymeleaf/README.md +++ b/spring-thymeleaf/README.md @@ -8,6 +8,7 @@ - [Thymeleaf: Custom Layout Dialect](http://www.baeldung.com/thymeleaf-spring-layouts) - [Spring and Thymeleaf 3: Expressions](http://www.baeldung.com/spring-thymeleaf-3-expressions) - [Spring MVC + Thymeleaf 3.0: New Features](http://www.baeldung.com/spring-thymeleaf-3) +- [How to Work with Dates in Thymeleaef](http://www.baeldung.com/dates-in-thymeleaf) ### Build the Project From a0de46efb99efe3ca0151d01b16ca343d6ea4af1 Mon Sep 17 00:00:00 2001 From: Daniele Demichelis Date: Tue, 10 Jan 2017 19:54:07 +0100 Subject: [PATCH 04/14] Intro to Spring Remoting with HTTP Invokers (#964) * First test with log4j rolling appenders * small fix * Log4j rolling appender * First set up with rolling file on log4j 2 * Added logback code. * log4j2 more detailed example * log4j2 more detailed example * Improved names and examples * Fixed configurations * improved configs * formatted * Final fix * fixed formatting * Formatting fix * Fix sample apps to avoid try / catch * Fix request to replace files * Fix end lines * Log4j2 logger is shot down at the end. * Initial commit, the server starts launched from maven * made room for client and server projects * made room for client and server projects * base example works * poms restructured * packages restructured * packages restructured * Some renaming and a proper formatting string * Small renamings * Small renamings * Fixed invoked URL in client through fixing bean name --- spring-remoting/pom.xml | 109 ++++++++++++++++++ spring-remoting/remoting-http/api/pom.xml | 14 +++ .../main/java/com/baeldung/api/Address.java | 26 +++++ .../main/java/com/baeldung/api/Booking.java | 53 +++++++++ .../com/baeldung/api/BookingException.java | 7 ++ .../com/baeldung/api/CabBookingService.java | 5 + spring-remoting/remoting-http/client/pom.xml | 30 +++++ .../com/baeldug/client/CabBookingClient.java | 25 ++++ .../main/java/com/baeldug/client/Main.java | 34 ++++++ spring-remoting/remoting-http/pom.xml | 20 ++++ spring-remoting/remoting-http/server/pom.xml | 65 +++++++++++ .../remoting-http/server/readme.md | 12 ++ .../com/baeldung/server/CabBookingConfig.java | 10 ++ .../server/CabBookingInitializer.java | 34 ++++++ .../server/CabBookingServiceImpl.java | 26 +++++ .../com/baeldung/server/DispatcherConfig.java | 18 +++ .../server/src/main/resources/logback.xml | 27 +++++ 17 files changed, 515 insertions(+) create mode 100644 spring-remoting/pom.xml create mode 100644 spring-remoting/remoting-http/api/pom.xml create mode 100644 spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Address.java create mode 100644 spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Booking.java create mode 100644 spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/BookingException.java create mode 100644 spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/CabBookingService.java create mode 100644 spring-remoting/remoting-http/client/pom.xml create mode 100644 spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/CabBookingClient.java create mode 100644 spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/Main.java create mode 100644 spring-remoting/remoting-http/pom.xml create mode 100644 spring-remoting/remoting-http/server/pom.xml create mode 100644 spring-remoting/remoting-http/server/readme.md create mode 100644 spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingConfig.java create mode 100644 spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingInitializer.java create mode 100644 spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java create mode 100644 spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/DispatcherConfig.java create mode 100644 spring-remoting/remoting-http/server/src/main/resources/logback.xml diff --git a/spring-remoting/pom.xml b/spring-remoting/pom.xml new file mode 100644 index 0000000000..cfb4af9d85 --- /dev/null +++ b/spring-remoting/pom.xml @@ -0,0 +1,109 @@ + + + 4.0.0 + com.baeldung + spring-remoting + 1.0-SNAPSHOT + pom + + + 3.6.0 + 3.0.0 + + 3.1.0 + 1.1.7 + 4.2.4.RELEASE + + + + + + + + org.springframework + spring-core + ${spring.version} + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-web + ${spring.version} + + + org.springframework + spring-webmvc + ${spring.version} + + + + + ch.qos.logback + logback-core + ${logback.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + javax.servlet + javax.servlet-api + ${servlet.version} + provided + + + + + ${project.groupId} + api + ${project.version} + + + + + + + + + + + + maven-compiler-plugin + ${maven-compiler-plugin.version} + + true + true + 1.8 + 1.8 + UTF-8 + true + true + + + + + maven-war-plugin + 3.0.0 + + false + + + + + + + + remoting-http + + + \ No newline at end of file diff --git a/spring-remoting/remoting-http/api/pom.xml b/spring-remoting/remoting-http/api/pom.xml new file mode 100644 index 0000000000..633217f7de --- /dev/null +++ b/spring-remoting/remoting-http/api/pom.xml @@ -0,0 +1,14 @@ + + + + spring-remoting-http + com.baeldung + 1.0-SNAPSHOT + + 4.0.0 + api + spring-remoting-http-api + API definition shared between client and server. + \ No newline at end of file diff --git a/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Address.java b/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Address.java new file mode 100644 index 0000000000..f2382fabd9 --- /dev/null +++ b/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Address.java @@ -0,0 +1,26 @@ +package com.baeldung.api; + +import java.io.Serializable; + +public class Address implements Serializable{ + + private String address; + private String countryCode; + + public Address(String address, String countryCode) { + this.address = address; + this.countryCode = countryCode; + } + + public String getAddress() { + return address; + } + + public String getCountryCode() { + return countryCode; + } + + @Override public String toString() { + return address + " (" + countryCode + ")"; + } +} diff --git a/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Booking.java b/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Booking.java new file mode 100644 index 0000000000..0f52a7bfbd --- /dev/null +++ b/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Booking.java @@ -0,0 +1,53 @@ +package com.baeldung.api; + +import java.io.Serializable; +import java.util.Date; + +public class Booking implements Serializable { + + private int costInCent; + private int etaInSeconds; + private String bookingCode; + private Date pickUptime; + private Address pickUpAddress; + private Address dropOffAddress; + + public Booking(Address pickUpAddress, Date pickUptime, Address dropOffAddress, int costInCent, int etaInSeconds, String bookingCode) { + this.costInCent = costInCent; + this.etaInSeconds = etaInSeconds; + this.bookingCode = bookingCode; + this.pickUptime = pickUptime; + this.pickUpAddress = pickUpAddress; + this.dropOffAddress = dropOffAddress; + } + + public int getCostInCent() { + return costInCent; + } + + public int getEtaInSeconds() { + return etaInSeconds; + } + + public String getBookingCode() { + return bookingCode; + } + + public Date getPickUptime() { + return pickUptime; + } + + public Address getDropOffAddress() { + return dropOffAddress; + } + + @Override public String toString() { + return String.format("Booking: pick up @ %tr in %s, drop down in %s after %d minutes, %.2f $.", pickUptime, pickUpAddress, dropOffAddress, etaInSeconds/60, costInCent/100.0); + } + + public static void main(String[] args) throws InterruptedException { + System.out.println( + new Booking(new Address("a", "b"), new Date(), new Address("c", "d"), 123_00, 600, "abc") + ); + } +} diff --git a/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/BookingException.java b/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/BookingException.java new file mode 100644 index 0000000000..4099db2908 --- /dev/null +++ b/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/BookingException.java @@ -0,0 +1,7 @@ +package com.baeldung.api; + +public class BookingException extends Exception { + public BookingException(String message) { + super(message); + } +} diff --git a/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/CabBookingService.java b/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/CabBookingService.java new file mode 100644 index 0000000000..25b27264e8 --- /dev/null +++ b/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/CabBookingService.java @@ -0,0 +1,5 @@ +package com.baeldung.api; + +public interface CabBookingService { + Booking bookPickUp(Address pickUpLocation, Address dropOffLocation, int pax) throws BookingException; +} diff --git a/spring-remoting/remoting-http/client/pom.xml b/spring-remoting/remoting-http/client/pom.xml new file mode 100644 index 0000000000..77891c106a --- /dev/null +++ b/spring-remoting/remoting-http/client/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + + + com.baeldung + spring-remoting-http + 1.0-SNAPSHOT + + + spring-remoting-http-client + Shows how to invoke a remote service using Spring Remoting. + + + + + org.springframework + spring-web + + + + + ${project.groupId} + api + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/CabBookingClient.java b/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/CabBookingClient.java new file mode 100644 index 0000000000..7cc8e5183c --- /dev/null +++ b/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/CabBookingClient.java @@ -0,0 +1,25 @@ +package com.baeldug.client; + +import com.baeldung.api.*; + +public class CabBookingClient { + + private CabBookingService cabService; + + public CabBookingClient(CabBookingService cabService) { + this.cabService = cabService; + } + + public void run() { + + Address pickUp = new Address("13 Seagate Blvd, Key Largo, FL 33037", "US"); + Address dropDown = new Address("91831 Overseas Hwy, Tavernier, FL 33070", "US"); + try { + System.out.println( cabService.bookPickUp(pickUp, dropDown, 3) ); + } catch (BookingException e) { + e.printStackTrace(); + } + + } + +} diff --git a/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/Main.java b/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/Main.java new file mode 100644 index 0000000000..0ddb37c508 --- /dev/null +++ b/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/Main.java @@ -0,0 +1,34 @@ +package com.baeldug.client; + +import com.baeldung.api.CabBookingService; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean; + +@Configuration +public class Main { + + @Bean + public HttpInvokerProxyFactoryBean invoker() { + HttpInvokerProxyFactoryBean invoker = new HttpInvokerProxyFactoryBean(); + invoker.setServiceUrl("http://localhost:9090/spring-remoting-http-server/booking"); + invoker.setServiceInterface(CabBookingService.class); + return invoker; + } + + @Bean + public CabBookingClient client(CabBookingService service){ + return new CabBookingClient(service); + } + + public static void main(String[] args) throws InterruptedException { + AnnotationConfigApplicationContext rootContext = + new AnnotationConfigApplicationContext(); + rootContext.scan(Main.class.getPackage().getName()); + rootContext.refresh(); + CabBookingClient bean = rootContext.getBean(CabBookingClient.class); + bean.run(); + } + +} diff --git a/spring-remoting/remoting-http/pom.xml b/spring-remoting/remoting-http/pom.xml new file mode 100644 index 0000000000..0d08779bd7 --- /dev/null +++ b/spring-remoting/remoting-http/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + com.baeldung + spring-remoting + 1.0-SNAPSHOT + + spring-remoting-http + Parent for all modules related to HTTP Spring Remoting + pom + + + server + client + api + + \ No newline at end of file diff --git a/spring-remoting/remoting-http/server/pom.xml b/spring-remoting/remoting-http/server/pom.xml new file mode 100644 index 0000000000..32a99716a5 --- /dev/null +++ b/spring-remoting/remoting-http/server/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + com.baeldung + spring-remoting-http + 1.0-SNAPSHOT + + war + + spring-remoting-http-server + Shows how to expose a service using Spring Remoting + + + 2.2 + + + + + + + + + org.springframework + spring-webmvc + + + + + javax.servlet + javax.servlet-api + + + + + ${project.groupId} + api + + + + + + + + maven-compiler-plugin + + + + maven-war-plugin + + + + org.apache.tomcat.maven + tomcat7-maven-plugin + ${tomcat7-maven-plugin.version} + + 9090 + + + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-http/server/readme.md b/spring-remoting/remoting-http/server/readme.md new file mode 100644 index 0000000000..4a2abb5d03 --- /dev/null +++ b/spring-remoting/remoting-http/server/readme.md @@ -0,0 +1,12 @@ +Build and launch with the following command. + + mvn clean package tomcat7:run-war + +Exposed service is available at following URL. + + http://localhost:9090/spring-remoting-http-server/account + +## References + + + diff --git a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingConfig.java b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingConfig.java new file mode 100644 index 0000000000..146d2ecadb --- /dev/null +++ b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingConfig.java @@ -0,0 +1,10 @@ +package com.baeldung.server; + +import org.springframework.context.annotation.Configuration; + +@Configuration +public class CabBookingConfig { + + + +} diff --git a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingInitializer.java b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingInitializer.java new file mode 100644 index 0000000000..53b3fd5faf --- /dev/null +++ b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingInitializer.java @@ -0,0 +1,34 @@ +package com.baeldung.server; + +import org.springframework.web.WebApplicationInitializer; +import org.springframework.web.context.ContextLoaderListener; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import org.springframework.web.servlet.DispatcherServlet; + +import javax.servlet.ServletContext; +import javax.servlet.ServletRegistration; + +public class CabBookingInitializer implements WebApplicationInitializer { + + @Override + public void onStartup(ServletContext container) { + AnnotationConfigWebApplicationContext rootContext = + new AnnotationConfigWebApplicationContext(); + rootContext.register(CabBookingConfig.class); + + // Manage the lifecycle of the root application context + container.addListener(new ContextLoaderListener(rootContext)); + + // Create the dispatcher servlet's Spring application context + AnnotationConfigWebApplicationContext dispatcherContext = + new AnnotationConfigWebApplicationContext(); + dispatcherContext.register(DispatcherConfig.class); + + // Register and map the dispatcher servlet + ServletRegistration.Dynamic dispatcher = + container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext)); + dispatcher.setLoadOnStartup(1); + dispatcher.addMapping("/*"); + } + +} diff --git a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java new file mode 100644 index 0000000000..5f43c7e707 --- /dev/null +++ b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java @@ -0,0 +1,26 @@ +package com.baeldung.server; + +import com.baeldung.api.Address; +import com.baeldung.api.Booking; +import com.baeldung.api.BookingException; +import com.baeldung.api.CabBookingService; + +import java.util.Date; + +import static java.lang.Math.random; +import static java.lang.System.currentTimeMillis; +import static java.util.UUID.randomUUID; + +public class CabBookingServiceImpl implements CabBookingService { + + @Override public Booking bookPickUp(Address pickUpLocation, Address dropOffLocation, int pax) throws BookingException { + if(random()<0.3){ + throw new BookingException("Cab unavailable"); + } + int tripTimeInMinutes = (int) (5 + random() * 15); + int costInCent = 15_00 + tripTimeInMinutes * 5 * pax; + Date pickUpDate = new Date((long) (currentTimeMillis() + (1000 * 60 * random() * 15))); + return new Booking(pickUpLocation, pickUpDate, dropOffLocation, costInCent, tripTimeInMinutes * 60, + randomUUID().toString()); + } +} diff --git a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/DispatcherConfig.java b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/DispatcherConfig.java new file mode 100644 index 0000000000..8f9391f8ac --- /dev/null +++ b/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/DispatcherConfig.java @@ -0,0 +1,18 @@ +package com.baeldung.server; + +import com.baeldung.api.CabBookingService; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter; + +@Configuration +public class DispatcherConfig { + + @Bean(name = "/booking") HttpInvokerServiceExporter accountService() { + HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter(); + exporter.setService( new CabBookingServiceImpl() ); + exporter.setServiceInterface( CabBookingService.class ); + return exporter; + } + +} diff --git a/spring-remoting/remoting-http/server/src/main/resources/logback.xml b/spring-remoting/remoting-http/server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7a03574f40 --- /dev/null +++ b/spring-remoting/remoting-http/server/src/main/resources/logback.xml @@ -0,0 +1,27 @@ + + + + + + + + ${logPattern} + + + + + C:\Users\danidemi\tmp\baledung\app.log + false + + ${logPattern} + + + + + + + + \ No newline at end of file From 4772976bdac504ef2d4f7652024da7588e0f7a01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Soares?= Date: Wed, 11 Jan 2017 02:54:12 +0000 Subject: [PATCH 05/14] Exercise snippets only in tests (#982) * Exercise snippets only in tests * Increase Jsoup version --- jsoup/pom.xml | 2 +- .../java/com/baeldung/jsoup/JsoupParser.java | 91 ------------------- .../com/baeldung/jsoup/JsoupParserTest.java | 91 +++++++++++++++++-- 3 files changed, 83 insertions(+), 101 deletions(-) delete mode 100644 jsoup/src/main/java/com/baeldung/jsoup/JsoupParser.java diff --git a/jsoup/pom.xml b/jsoup/pom.xml index 343e139b46..25551cb3d6 100644 --- a/jsoup/pom.xml +++ b/jsoup/pom.xml @@ -25,6 +25,6 @@ 1.8 1.8 - 1.10.1 + 1.10.2 diff --git a/jsoup/src/main/java/com/baeldung/jsoup/JsoupParser.java b/jsoup/src/main/java/com/baeldung/jsoup/JsoupParser.java deleted file mode 100644 index cb86b16888..0000000000 --- a/jsoup/src/main/java/com/baeldung/jsoup/JsoupParser.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.baeldung.jsoup; - -import java.io.IOException; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.parser.Tag; -import org.jsoup.select.Elements; - -public class JsoupParser { - - Document doc; - - public void loadDocument(String blogUrl) throws IOException { - doc = Jsoup.connect(blogUrl).get(); - } - - void loadDocumentCustomized(String blogUrl) throws IOException { - doc = Jsoup.connect(blogUrl) - .userAgent("Mozilla") - .timeout(5000) - .cookie("cookiename", "val234") - .cookie("anothercookie", "ilovejsoup") - .referrer("http://google.com") - .header("headersecurity", "xyz123") - .get(); - } - - void examplesSelectors() { - Elements links = doc.select("a"); - Elements logo = doc.select(".spring-logo--container"); - Elements pagination = doc.select("#pagination_control"); - Elements divsDescendant = doc.select("header div"); - Elements divsDirect = doc.select("header > div"); - - Element pag = doc.getElementById("pagination_control"); - Elements desktopOnly = doc.getElementsByClass("desktopOnly"); - - Elements sections = doc.select("section"); - Element firstSection = sections.first(); - Elements sectionParagraphs = firstSection.select(".paragraph"); - } - - void examplesTraversing() { - Elements sections = doc.select("section"); - - Element firstSection = sections.first(); - Element lastSection = sections.last(); - Element secondSection = sections.get(2); - Elements allParents = firstSection.parents(); - Element parent = firstSection.parent(); - Elements children = firstSection.children(); - Elements siblings = firstSection.siblingElements(); - - sections.stream().forEach(el -> System.out.println("section: " + el)); - } - - void examplesExtracting() { - Element firstArticle = doc.select("article").first(); - Element timeElement = firstArticle.select("time").first(); - String dateTimeOfFirstArticle = timeElement.attr("datetime"); - Element sectionDiv = firstArticle.select("section div").first(); - String sectionDivText = sectionDiv.text(); - String articleHtml = firstArticle.html(); - String outerHtml = firstArticle.outerHtml(); - } - - void examplesModifying() { - Element firstArticle = doc.select("article").first(); - Element timeElement = firstArticle.select("time").first(); - Element sectionDiv = firstArticle.select("section div").first(); - - String dateTimeOfFirstArticle = timeElement.attr("datetime"); - timeElement.attr("datetime", "2016-12-16 15:19:54.3"); - sectionDiv.text("foo bar"); - firstArticle.select("h2").html("
"); - - Element link = new Element(Tag.valueOf("a"), "") - .text("Checkout this amazing website!") - .attr("href", "http://baeldung.com") - .attr("target", "_blank"); - firstArticle.appendChild(link); - - doc.select("li.navbar-link").remove(); - firstArticle.select("img").remove(); - } - - String getTidyHtml() { - return doc.html(); - } -} diff --git a/jsoup/src/test/java/com/baeldung/jsoup/JsoupParserTest.java b/jsoup/src/test/java/com/baeldung/jsoup/JsoupParserTest.java index 85fd3c3459..aa8b8bad96 100644 --- a/jsoup/src/test/java/com/baeldung/jsoup/JsoupParserTest.java +++ b/jsoup/src/test/java/com/baeldung/jsoup/JsoupParserTest.java @@ -2,6 +2,11 @@ package com.baeldung.jsoup; import java.io.IOException; import org.jsoup.HttpStatusException; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.parser.Tag; +import org.jsoup.select.Elements; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.junit.Before; @@ -9,28 +14,96 @@ import org.junit.Test; public class JsoupParserTest { - JsoupParser jsoupParser; + Document doc; @Before - public void setUp() { - jsoupParser = new JsoupParser(); + public void setUp() throws IOException { + doc = Jsoup.connect("https://spring.io/blog").get(); } @Test - public void test404() throws IOException { + public void loadDocument404() throws IOException { try { - jsoupParser.loadDocument("https://spring.io/will-not-be-found"); + doc = Jsoup.connect("https://spring.io/will-not-be-found").get(); } catch (HttpStatusException ex) { assertEquals(404, ex.getStatusCode()); } } @Test - public void testChange() throws IOException { - jsoupParser.loadDocument("http://spring.io/blog"); + public void loadDocumentCustomized() throws IOException { + doc = Jsoup.connect("https://spring.io/blog") + .userAgent("Mozilla") + .timeout(5000) + .cookie("cookiename", "val234") + .cookie("anothercookie", "ilovejsoup") + .referrer("http://google.com") + .header("headersecurity", "xyz123") + .get(); + } - jsoupParser.examplesModifying(); + @Test + public void examplesSelectors() { + Elements links = doc.select("a"); + Elements logo = doc.select(".spring-logo--container"); + Elements pagination = doc.select("#pagination_control"); + Elements divsDescendant = doc.select("header div"); + Elements divsDirect = doc.select("header > div"); - assertTrue(jsoupParser.getTidyHtml().contains("http://baeldung.com")); + Element pag = doc.getElementById("pagination_control"); + Elements desktopOnly = doc.getElementsByClass("desktopOnly"); + + Elements sections = doc.select("section"); + Element firstSection = sections.first(); + Elements sectionParagraphs = firstSection.select(".paragraph"); + } + + @Test + public void examplesTraversing() { + Elements sections = doc.select("section"); + + Element firstSection = sections.first(); + Element lastSection = sections.last(); + Element secondSection = sections.get(2); + Elements allParents = firstSection.parents(); + Element parent = firstSection.parent(); + Elements children = firstSection.children(); + Elements siblings = firstSection.siblingElements(); + + sections.stream().forEach(el -> System.out.println("section: " + el)); + } + + @Test + public void examplesExtracting() { + Element firstArticle = doc.select("article").first(); + Element timeElement = firstArticle.select("time").first(); + String dateTimeOfFirstArticle = timeElement.attr("datetime"); + Element sectionDiv = firstArticle.select("section div").first(); + String sectionDivText = sectionDiv.text(); + String articleHtml = firstArticle.html(); + String outerHtml = firstArticle.outerHtml(); + } + + @Test + public void examplesModifying() { + Element firstArticle = doc.select("article").first(); + Element timeElement = firstArticle.select("time").first(); + Element sectionDiv = firstArticle.select("section div").first(); + + String dateTimeOfFirstArticle = timeElement.attr("datetime"); + timeElement.attr("datetime", "2016-12-16 15:19:54.3"); + sectionDiv.text("foo bar"); + firstArticle.select("h2").html("
"); + + Element link = new Element(Tag.valueOf("a"), "") + .text("Checkout this amazing website!") + .attr("href", "http://baeldung.com") + .attr("target", "_blank"); + firstArticle.appendChild(link); + + doc.select("li.navbar-link").remove(); + firstArticle.select("img").remove(); + + assertTrue(doc.html().contains("http://baeldung.com")); } } From 94c315c1c2071d33135821f9348a483d43a3c09d Mon Sep 17 00:00:00 2001 From: pivovarit Date: Wed, 11 Jan 2017 07:20:55 +0100 Subject: [PATCH 06/14] Refactor JsoupParserTest --- .../java/com/baeldung/jsoup/JsoupParserTest.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/jsoup/src/test/java/com/baeldung/jsoup/JsoupParserTest.java b/jsoup/src/test/java/com/baeldung/jsoup/JsoupParserTest.java index aa8b8bad96..ba6d7358bc 100644 --- a/jsoup/src/test/java/com/baeldung/jsoup/JsoupParserTest.java +++ b/jsoup/src/test/java/com/baeldung/jsoup/JsoupParserTest.java @@ -1,17 +1,19 @@ package com.baeldung.jsoup; -import java.io.IOException; import org.jsoup.HttpStatusException; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.parser.Tag; import org.jsoup.select.Elements; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + public class JsoupParserTest { Document doc; @@ -70,7 +72,7 @@ public class JsoupParserTest { Elements children = firstSection.children(); Elements siblings = firstSection.siblingElements(); - sections.stream().forEach(el -> System.out.println("section: " + el)); + sections.forEach(el -> System.out.println("section: " + el)); } @Test @@ -96,9 +98,9 @@ public class JsoupParserTest { firstArticle.select("h2").html("
"); Element link = new Element(Tag.valueOf("a"), "") - .text("Checkout this amazing website!") - .attr("href", "http://baeldung.com") - .attr("target", "_blank"); + .text("Checkout this amazing website!") + .attr("href", "http://baeldung.com") + .attr("target", "_blank"); firstArticle.appendChild(link); doc.select("li.navbar-link").remove(); From 3fc01ee7e0db0610711710e5072046383873e50c Mon Sep 17 00:00:00 2001 From: eugenp Date: Wed, 11 Jan 2017 11:45:43 +0200 Subject: [PATCH 07/14] minor formatting cleanup --- annotations/pom.xml | 5 +- apache-cxf/pom.xml | 8 +- apache-fop/pom.xml | 295 ++++++++++++++++++------------------ aspectj/pom.xml | 85 ++++------- assertj/pom.xml | 4 +- autovalue/pom.xml | 2 +- cdi/pom.xml | 6 +- core-java-9/pom.xml | 141 +++++++++-------- couchbase-sdk/pom.xml | 188 +++++++++++------------ deltaspike/pom.xml | 74 ++++----- dozer/pom.xml | 8 +- ejb/pom.xml | 10 +- enterprise-patterns/pom.xml | 7 +- feign/pom.xml | 2 +- 14 files changed, 396 insertions(+), 439 deletions(-) diff --git a/annotations/pom.xml b/annotations/pom.xml index f691674cf1..0ddc17f8a7 100644 --- a/annotations/pom.xml +++ b/annotations/pom.xml @@ -1,7 +1,6 @@ - + parent-modules com.baeldung diff --git a/apache-cxf/pom.xml b/apache-cxf/pom.xml index e2cd7d344a..6849452908 100644 --- a/apache-cxf/pom.xml +++ b/apache-cxf/pom.xml @@ -5,20 +5,20 @@ apache-cxf 0.0.1-SNAPSHOT pom - + cxf-introduction cxf-spring cxf-jaxrs-implementation cxf-aegis - + 4.12 3.6.0 1.5.0 - + junit @@ -27,7 +27,7 @@ test - + install diff --git a/apache-fop/pom.xml b/apache-fop/pom.xml index 4dd61d8f4e..6f89497a7d 100644 --- a/apache-fop/pom.xml +++ b/apache-fop/pom.xml @@ -1,154 +1,155 @@ - - 4.0.0 - com.baeldung - apache-fop - 0.1-SNAPSHOT + + 4.0.0 + com.baeldung + apache-fop + 0.1-SNAPSHOT - apache-fop + apache-fop - + - + - - org.slf4j - slf4j-api - ${org.slf4j.version} - - - ch.qos.logback - logback-classic - ${logback.version} - - - - org.slf4j - jcl-over-slf4j - ${org.slf4j.version} - - - - org.slf4j - log4j-over-slf4j - ${org.slf4j.version} - + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + + org.slf4j + jcl-over-slf4j + ${org.slf4j.version} + + + + org.slf4j + log4j-over-slf4j + ${org.slf4j.version} + - + - - junit - junit - ${junit.version} - test - + + junit + junit + ${junit.version} + test + - - org.hamcrest - hamcrest-core - ${org.hamcrest.version} - test - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - + + org.hamcrest + hamcrest-core + ${org.hamcrest.version} + test + + + org.hamcrest + hamcrest-library + ${org.hamcrest.version} + test + - - org.mockito - mockito-core - ${mockito.version} - test - + + org.mockito + mockito-core + ${mockito.version} + test + - + - - org.apache.xmlgraphics - fop - ${fop.version} - - - org.apache.avalon.framework - avalon-framework-api - - - org.apache.avalon.framework - avalon-framework-impl - - - + + org.apache.xmlgraphics + fop + ${fop.version} + + + org.apache.avalon.framework + avalon-framework-api + + + org.apache.avalon.framework + avalon-framework-impl + + + - - avalon-framework - avalon-framework-api - ${avalon-framework.version} - - - avalon-framework - avalon-framework-impl - ${avalon-framework.version} - + + avalon-framework + avalon-framework-api + ${avalon-framework.version} + + + avalon-framework + avalon-framework-impl + ${avalon-framework.version} + - - org.dbdoclet - dbdoclet - ${dbdoclet.version} - + + org.dbdoclet + dbdoclet + ${dbdoclet.version} + - - org.dbdoclet - herold - 6.1.0 - system - ${basedir}/src/test/resources/jars/herold.jar - - - - net.sf.jtidy - jtidy - ${jtidy.version} - + + org.dbdoclet + herold + 6.1.0 + system + ${basedir}/src/test/resources/jars/herold.jar + - + + net.sf.jtidy + jtidy + ${jtidy.version} + - - apache-fop - - - src/main/resources - true - - + - + + apache-fop + + + src/main/resources + true + + - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - 1.7 - 1.7 - - + - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.7 + 1.7 + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + **/*IntegrationTest.java **/*LiveTest.java - - - + + + - + - + @@ -170,7 +171,7 @@ **/*IntegrationTest.java - **/*LiveTest.java + **/*LiveTest.java @@ -185,25 +186,25 @@ - - - 1.1 - 4.3 - 8.0.2 - r938 - - 1.7.21 - 1.1.7 - - 1.3 - 4.12 - 1.10.19 + + 1.1 + 4.3 + 8.0.2 + r938 + + 1.7.21 + 1.1.7 - - 3.6.0 - 2.19.1 + + 1.3 + 4.12 + 1.10.19 - + + 3.6.0 + 2.19.1 + + \ No newline at end of file diff --git a/aspectj/pom.xml b/aspectj/pom.xml index 6e7ef1b961..90b527c14f 100644 --- a/aspectj/pom.xml +++ b/aspectj/pom.xml @@ -12,32 +12,32 @@ aspectjrt ${aspectj.version} - + org.aspectj aspectjweaver ${aspectj.version} - + org.slf4j slf4j-api ${org.slf4j.version} - + ch.qos.logback logback-classic ${logback.version} - + ch.qos.logback logback-core ${logback.version} - + junit @@ -46,34 +46,34 @@ - org.springframework - spring-context - 4.3.4.RELEASE + org.springframework + spring-context + 4.3.4.RELEASE - org.springframework - spring-beans - 4.3.4.RELEASE + org.springframework + spring-beans + 4.3.4.RELEASE - org.springframework - spring-core - 4.3.4.RELEASE + org.springframework + spring-core + 4.3.4.RELEASE - cglib - cglib - 3.2.4 + cglib + cglib + 3.2.4 - org.springframework - spring-aop - 4.3.4.RELEASE + org.springframework + spring-aop + 4.3.4.RELEASE - log4j - log4j - 1.2.17 + log4j + log4j + 1.2.17 @@ -95,9 +95,9 @@ ${source.version} ${source.version} - + - + org.codehaus.mojo aspectj-maven-plugin @@ -111,41 +111,22 @@ ignore ${project.build.sourceEncoding} - - + + compile - test-compile + test-compile - - - + + diff --git a/assertj/pom.xml b/assertj/pom.xml index 0b3bcbacdb..032f33c89d 100644 --- a/assertj/pom.xml +++ b/assertj/pom.xml @@ -54,8 +54,8 @@ 3.1.0 4.12 3.6.1 - + 3.6.0 - + \ No newline at end of file diff --git a/autovalue/pom.xml b/autovalue/pom.xml index 57c4662e5c..32616dc8bc 100644 --- a/autovalue/pom.xml +++ b/autovalue/pom.xml @@ -41,5 +41,5 @@ 4.12 3.6.0 - + diff --git a/cdi/pom.xml b/cdi/pom.xml index 231390ea5c..e5aaeb2c7b 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -45,7 +45,7 @@ - + @@ -61,7 +61,7 @@ - + integration @@ -101,7 +101,7 @@ 1.8.9 2.4.1.Final 4.12 - 2.19.1 + 2.19.1 \ No newline at end of file diff --git a/core-java-9/pom.xml b/core-java-9/pom.xml index bf9325c935..decba19c53 100644 --- a/core-java-9/pom.xml +++ b/core-java-9/pom.xml @@ -1,91 +1,88 @@ - - 4.0.0 - com.baeldung - core-java9 - 0.2-SNAPSHOT + + 4.0.0 + com.baeldung + core-java9 + 0.2-SNAPSHOT - core-java9 + core-java9 - - - apache.snapshots - http://repository.apache.org/snapshots/ - - + + + apache.snapshots + http://repository.apache.org/snapshots/ + + - + - - org.slf4j - slf4j-api - ${org.slf4j.version} - + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + org.hamcrest + hamcrest-library + ${org.hamcrest.version} + test + + + junit + junit + ${junit.version} + test + - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - + + org.mockito + mockito-core + ${mockito.version} + test + - - junit - junit - ${junit.version} - test - + - - org.mockito - mockito-core - ${mockito.version} - test - + + core-java-9 - + - - core-java-9 + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.9 + 1.9 + true + + - + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - 1.9 - 1.9 - true - - + - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - + - + + + 1.7.21 - + + 3.6-jigsaw-SNAPSHOT + 2.19.1 - - - 1.7.21 - - - 3.6-jigsaw-SNAPSHOT - 2.19.1 - - - 1.3 - 4.12 - 1.10.19 - + + 1.3 + 4.12 + 1.10.19 + diff --git a/couchbase-sdk/pom.xml b/couchbase-sdk/pom.xml index 6462cfb57a..301fd81c51 100644 --- a/couchbase-sdk/pom.xml +++ b/couchbase-sdk/pom.xml @@ -1,91 +1,91 @@ - 4.0.0 - com.baeldung - couchbase-sdk - 0.1-SNAPSHOT - jar - couchbase-sdk - Couchbase SDK Tutorials + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + com.baeldung + couchbase-sdk + 0.1-SNAPSHOT + jar + couchbase-sdk + Couchbase SDK Tutorials - - - - com.couchbase.client - java-client - ${couchbase.client.version} - + + + + com.couchbase.client + java-client + ${couchbase.client.version} + - - - org.springframework - spring-context - ${spring-framework.version} - - - org.springframework - spring-context-support - ${spring-framework.version} - + + + org.springframework + spring-context + ${spring-framework.version} + + + org.springframework + spring-context-support + ${spring-framework.version} + - - - org.slf4j - slf4j-api - ${org.slf4j.version} - compile - - - ch.qos.logback - logback-classic - ${logback.version} - - - org.slf4j - jcl-over-slf4j - ${org.slf4j.version} - - - org.slf4j - log4j-over-slf4j - ${org.slf4j.version} - + + + org.slf4j + slf4j-api + ${org.slf4j.version} + compile + + + ch.qos.logback + logback-classic + ${logback.version} + + + org.slf4j + jcl-over-slf4j + ${org.slf4j.version} + + + org.slf4j + log4j-over-slf4j + ${org.slf4j.version} + - - - org.springframework - spring-test - ${spring-framework.version} - test - - - junit - junit - ${junit.version} - test - - - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - test - - + + + org.springframework + spring-test + ${spring-framework.version} + test + + + junit + junit + ${junit.version} + test + - - - - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${java.version} - ${java.version} - - - + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + test + + + + + + + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + + + org.apache.maven.plugins maven-surefire-plugin ${maven-surefire-plugin.version} @@ -96,20 +96,20 @@ - - + + - - 1.8 - UTF-8 - 2.3.6 - 4.3.4.RELEASE - 1.1.7 - 1.7.21 - 4.12 - 3.5 - 3.6.0 + + 1.8 + UTF-8 + 2.3.6 + 4.3.4.RELEASE + 1.1.7 + 1.7.21 + 4.12 + 3.5 + 3.6.0 2.19.1 - + diff --git a/deltaspike/pom.xml b/deltaspike/pom.xml index b4a7657e97..141b5b0da6 100644 --- a/deltaspike/pom.xml +++ b/deltaspike/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung deltaspike @@ -19,21 +19,19 @@ - - - UTF-8 + + + + UTF-8 1.7.21 3.7.4 1.7.2 - + 1.0.2.Final - + 8.2.2.Final @@ -50,14 +48,11 @@ - + org.wildfly.bom jboss-javaee-7.0-with-tools @@ -77,43 +72,37 @@ - + - + javax.enterprise cdi-api provided - + org.jboss.spec.javax.annotation jboss-annotations-api_1.2_spec provided - + org.jboss.resteasy jaxrs-api provided - + org.hibernate.javax.persistence hibernate-jpa-2.1-api provided - + org.jboss.spec.javax.ejb jboss-ejb-api_3.2_spec @@ -135,8 +124,7 @@ - + org.jboss.spec.javax.faces jboss-jsf-api_2.2_spec @@ -145,16 +133,14 @@ - + org.hibernate hibernate-jpamodelgen provided - + org.hibernate hibernate-validator-annotation-processor @@ -169,8 +155,7 @@ - + org.jboss.arquillian.junit arquillian-junit-container @@ -225,8 +210,7 @@ - + ${project.artifactId} @@ -265,10 +249,8 @@ - - + + default true @@ -288,10 +270,8 @@ - - + + arq-wildfly-managed diff --git a/dozer/pom.xml b/dozer/pom.xml index 363285f619..56d5e889c3 100644 --- a/dozer/pom.xml +++ b/dozer/pom.xml @@ -1,11 +1,11 @@ 4.0.0 - + com.baeldung dozer 1.0 - + dozer @@ -54,7 +54,7 @@ - + 1.7.21 3.5 @@ -62,5 +62,5 @@ 4.12 3.6.0 - + diff --git a/ejb/pom.xml b/ejb/pom.xml index b00f80a817..bfcc972417 100755 --- a/ejb/pom.xml +++ b/ejb/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung.ejb ejb @@ -75,8 +75,8 @@ - - ejb-remote - ejb-client - + + ejb-remote + ejb-client + \ No newline at end of file diff --git a/enterprise-patterns/pom.xml b/enterprise-patterns/pom.xml index 763227e45b..1c895095dc 100644 --- a/enterprise-patterns/pom.xml +++ b/enterprise-patterns/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung.enterprise.patterns @@ -32,7 +31,7 @@ - + 3.6.0 diff --git a/feign/pom.xml b/feign/pom.xml index 721fa76682..160f37ec2c 100644 --- a/feign/pom.xml +++ b/feign/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung.feign From 9e48d87306d072eed11a48f3e564cab95f431348 Mon Sep 17 00:00:00 2001 From: Ahmed-Saied Date: Wed, 11 Jan 2017 22:29:25 +0200 Subject: [PATCH 08/14] Spring scheduling beyond scheduled (#984) --- .../ThreadPoolTaskSchedulerConfig.java | 41 ++++++++++++++++ .../ThreadPoolTaskSchedulerExamples.java | 47 +++++++++++++++++++ .../ThreadPoolTaskSchedulerTest.java | 16 +++++++ 3 files changed, 104 insertions(+) create mode 100644 spring-all/src/main/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerConfig.java create mode 100644 spring-all/src/main/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerExamples.java create mode 100644 spring-all/src/test/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerTest.java diff --git a/spring-all/src/main/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerConfig.java b/spring-all/src/main/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerConfig.java new file mode 100644 index 0000000000..342a5fe3e6 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerConfig.java @@ -0,0 +1,41 @@ +package org.baeldung.taskscheduler; + +import java.util.concurrent.TimeUnit; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.support.CronTrigger; +import org.springframework.scheduling.support.PeriodicTrigger; + +@Configuration +@ComponentScan(basePackages = "org.baeldung.taskscheduler", basePackageClasses = { ThreadPoolTaskSchedulerExamples.class }) +public class ThreadPoolTaskSchedulerConfig { + + @Bean + public ThreadPoolTaskScheduler threadPoolTaskScheduler() { + ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); + threadPoolTaskScheduler.setPoolSize(5); + threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler"); + return threadPoolTaskScheduler; + } + + @Bean + public CronTrigger cronTrigger() { + return new CronTrigger("10 * * * * ?"); + } + + @Bean + public PeriodicTrigger periodicTrigger() { + return new PeriodicTrigger(2000, TimeUnit.MICROSECONDS); + } + + @Bean + public PeriodicTrigger periodicFixedDelayTrigger() { + PeriodicTrigger periodicTrigger = new PeriodicTrigger(2000, TimeUnit.MICROSECONDS); + periodicTrigger.setFixedRate(true); + periodicTrigger.setInitialDelay(1000); + return periodicTrigger; + } +} \ No newline at end of file diff --git a/spring-all/src/main/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerExamples.java b/spring-all/src/main/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerExamples.java new file mode 100644 index 0000000000..7505b85516 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerExamples.java @@ -0,0 +1,47 @@ +package org.baeldung.taskscheduler; + +import java.util.Date; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.support.CronTrigger; +import org.springframework.scheduling.support.PeriodicTrigger; +import org.springframework.stereotype.Component; + +@Component +public class ThreadPoolTaskSchedulerExamples { + @Autowired + private ThreadPoolTaskScheduler taskScheduler; + + @Autowired + private CronTrigger cronTrigger; + + @Autowired + private PeriodicTrigger periodicTrigger; + + @PostConstruct + public void scheduleRunnableWithCronTrigger(){ + taskScheduler.schedule(new RunnableTask("Current Date"), new Date()); + taskScheduler.scheduleWithFixedDelay(new RunnableTask("Fixed 1 second Delay"), 1000); + taskScheduler.scheduleWithFixedDelay(new RunnableTask("Current Date Fixed 1 second Delay"),new Date() , 1000); + taskScheduler.scheduleAtFixedRate(new RunnableTask("Fixed Rate of 2 seconds"),new Date(), 2000); + taskScheduler.scheduleAtFixedRate(new RunnableTask("Fixed Rate of 2 seconds"), 2000); + taskScheduler.schedule(new RunnableTask("Cron Trigger"), cronTrigger); + taskScheduler.schedule(new RunnableTask("Periodic Trigger"), periodicTrigger); + } + + class RunnableTask implements Runnable{ + + private String message; + + public RunnableTask(String message){ + this.message = message; + } + @Override + public void run() { + System.out.println("Runnable Task with "+message+" on thread "+Thread.currentThread().getName()); + } + } +} \ No newline at end of file diff --git a/spring-all/src/test/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerTest.java b/spring-all/src/test/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerTest.java new file mode 100644 index 0000000000..cc247cb384 --- /dev/null +++ b/spring-all/src/test/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerTest.java @@ -0,0 +1,16 @@ +package org.baeldung.taskscheduler; + +import org.junit.Test; +import org.junit.runner.RunWith; +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 = { ThreadPoolTaskSchedulerConfig.class }, loader = AnnotationConfigContextLoader.class) +public class ThreadPoolTaskSchedulerTest { + @Test + public void testThreadPoolTaskSchedulerAnnotation() throws InterruptedException { + Thread.sleep(2550); + } +} \ No newline at end of file From 6afaa3b167ca734f458513385ae7cafa7f1bde5b Mon Sep 17 00:00:00 2001 From: Jeyvison Date: Wed, 11 Jan 2017 17:40:04 -0300 Subject: [PATCH 09/14] Gradle tutorial (#985) --- gradle-tutorial/build.gradle | 25 +++ gradle-tutorial/gradle.properties | 3 + .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53539 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + gradle-tutorial/gradlew | 160 ++++++++++++++++++ gradle-tutorial/gradlew.bat | 90 ++++++++++ gradle-tutorial/src/main/java/Main.java | 5 + 7 files changed, 289 insertions(+) create mode 100644 gradle-tutorial/build.gradle create mode 100644 gradle-tutorial/gradle.properties create mode 100644 gradle-tutorial/gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle-tutorial/gradle/wrapper/gradle-wrapper.properties create mode 100644 gradle-tutorial/gradlew create mode 100644 gradle-tutorial/gradlew.bat create mode 100644 gradle-tutorial/src/main/java/Main.java diff --git a/gradle-tutorial/build.gradle b/gradle-tutorial/build.gradle new file mode 100644 index 0000000000..fc561987f7 --- /dev/null +++ b/gradle-tutorial/build.gradle @@ -0,0 +1,25 @@ +apply plugin: 'java' +apply plugin: 'maven' + +repositories{ + mavenCentral() +} + +dependencies{ + compile 'org.springframework:spring-context:4.3.5.RELEASE' +} + +task hello { + println "this Baeldung's tutorial is ${awesomeness}" +} + +uploadArchives { + repositories { + mavenDeployer { + repository(url: 'http://yourmavenrepo/repository') { + authentication(userName: 'user', password: 'password'); + } + + } + } +} diff --git a/gradle-tutorial/gradle.properties b/gradle-tutorial/gradle.properties new file mode 100644 index 0000000000..41701e5a19 --- /dev/null +++ b/gradle-tutorial/gradle.properties @@ -0,0 +1,3 @@ +awesomeness=awesome +group=com.baeldung.tutorial +version=1.0.1 diff --git a/gradle-tutorial/gradle/wrapper/gradle-wrapper.jar b/gradle-tutorial/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..3391a4cdf6b4057b1289f45659e6e46fd9902ce6 GIT binary patch literal 53539 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 literal 0 HcmV?d00001 diff --git a/gradle-tutorial/gradle/wrapper/gradle-wrapper.properties b/gradle-tutorial/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..b601d97764 --- /dev/null +++ b/gradle-tutorial/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sat Dec 31 15:46:08 BRT 2016 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-3.2.1-bin.zip diff --git a/gradle-tutorial/gradlew b/gradle-tutorial/gradlew new file mode 100644 index 0000000000..9d82f78915 --- /dev/null +++ b/gradle-tutorial/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradle-tutorial/gradlew.bat b/gradle-tutorial/gradlew.bat new file mode 100644 index 0000000000..8a0b282aa6 --- /dev/null +++ b/gradle-tutorial/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/gradle-tutorial/src/main/java/Main.java b/gradle-tutorial/src/main/java/Main.java new file mode 100644 index 0000000000..10edd1840b --- /dev/null +++ b/gradle-tutorial/src/main/java/Main.java @@ -0,0 +1,5 @@ +public class Main{ + public static void main(String[] args){ + System.out.println("Baeldung Rocks"); + } +} From 133018305554af20dd1439f60a47d0e0119f2890 Mon Sep 17 00:00:00 2001 From: DOHA Date: Wed, 11 Jan 2017 22:47:52 +0200 Subject: [PATCH 10/14] fix tests --- .../HttpClientMultipartLiveTest.java | 53 ++++++++----- .../httpclient/HttpsClientSslLiveTest.java | 76 +++++++++++++------ 2 files changed, 86 insertions(+), 43 deletions(-) diff --git a/httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartLiveTest.java b/httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartLiveTest.java index 6fad126537..954236a56f 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartLiveTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartLiveTest.java @@ -28,13 +28,14 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; -@Ignore("Server is not available") public class HttpClientMultipartLiveTest { - private static final String SERVER = "http://echo.200please.com"; + // No longer available + // private static final String SERVER = "http://echo.200please.com"; + + private static final String SERVER = "http://posttestserver.com/post.php"; private static final String TEXTFILENAME = "temp.txt"; private static final String IMAGEFILENAME = "image.jpg"; private static final String ZIPFILENAME = "zipFile.zip"; @@ -46,7 +47,8 @@ public class HttpClientMultipartLiveTest { @Before public final void before() { - client = HttpClientBuilder.create().build(); + client = HttpClientBuilder.create() + .build(); post = new HttpPost(SERVER); } @@ -80,7 +82,9 @@ public class HttpClientMultipartLiveTest { @Test public final void givenFileandMultipleTextParts_whenUploadwithAddPart_thenNoExceptions() throws IOException { - final URL url = Thread.currentThread().getContextClassLoader().getResource("uploads/" + TEXTFILENAME); + final URL url = Thread.currentThread() + .getContextClassLoader() + .getResource("uploads/" + TEXTFILENAME); final File file = new File(url.getPath()); final FileBody fileBody = new FileBody(file, ContentType.DEFAULT_BINARY); @@ -97,11 +101,12 @@ public class HttpClientMultipartLiveTest { post.setEntity(entity); response = client.execute(post); - final int statusCode = response.getStatusLine().getStatusCode(); + final int statusCode = response.getStatusLine() + .getStatusCode(); final String responseString = getContent(); final String contentTypeInHeader = getContentTypeHeader(); assertThat(statusCode, equalTo(HttpStatus.SC_OK)); - assertTrue(responseString.contains("Content-Type: multipart/form-data;")); + // assertTrue(responseString.contains("Content-Type: multipart/form-data;")); assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;")); System.out.println(responseString); System.out.println("POST Content Type: " + contentTypeInHeader); @@ -109,7 +114,9 @@ public class HttpClientMultipartLiveTest { @Test public final void givenFileandTextPart_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoExeption() throws ClientProtocolException, IOException { - final URL url = Thread.currentThread().getContextClassLoader().getResource("uploads/" + TEXTFILENAME); + final URL url = Thread.currentThread() + .getContextClassLoader() + .getResource("uploads/" + TEXTFILENAME); final File file = new File(url.getPath()); final String message = "This is a multipart post"; final MultipartEntityBuilder builder = MultipartEntityBuilder.create(); @@ -119,11 +126,12 @@ public class HttpClientMultipartLiveTest { final HttpEntity entity = builder.build(); post.setEntity(entity); response = client.execute(post); - final int statusCode = response.getStatusLine().getStatusCode(); + final int statusCode = response.getStatusLine() + .getStatusCode(); final String responseString = getContent(); final String contentTypeInHeader = getContentTypeHeader(); assertThat(statusCode, equalTo(HttpStatus.SC_OK)); - assertTrue(responseString.contains("Content-Type: multipart/form-data;")); + // assertTrue(responseString.contains("Content-Type: multipart/form-data;")); assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;")); System.out.println(responseString); System.out.println("POST Content Type: " + contentTypeInHeader); @@ -131,8 +139,12 @@ public class HttpClientMultipartLiveTest { @Test public final void givenFileAndInputStreamandText_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoException() throws ClientProtocolException, IOException { - final URL url = Thread.currentThread().getContextClassLoader().getResource("uploads/" + ZIPFILENAME); - final URL url2 = Thread.currentThread().getContextClassLoader().getResource("uploads/" + IMAGEFILENAME); + final URL url = Thread.currentThread() + .getContextClassLoader() + .getResource("uploads/" + ZIPFILENAME); + final URL url2 = Thread.currentThread() + .getContextClassLoader() + .getResource("uploads/" + IMAGEFILENAME); final InputStream inputStream = new FileInputStream(url.getPath()); final File file = new File(url2.getPath()); final String message = "This is a multipart post"; @@ -144,11 +156,12 @@ public class HttpClientMultipartLiveTest { final HttpEntity entity = builder.build(); post.setEntity(entity); response = client.execute(post); - final int statusCode = response.getStatusLine().getStatusCode(); + final int statusCode = response.getStatusLine() + .getStatusCode(); final String responseString = getContent(); final String contentTypeInHeader = getContentTypeHeader(); assertThat(statusCode, equalTo(HttpStatus.SC_OK)); - assertTrue(responseString.contains("Content-Type: multipart/form-data;")); + // assertTrue(responseString.contains("Content-Type: multipart/form-data;")); assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;")); System.out.println(responseString); System.out.println("POST Content Type: " + contentTypeInHeader); @@ -166,11 +179,12 @@ public class HttpClientMultipartLiveTest { final HttpEntity entity = builder.build(); post.setEntity(entity); response = client.execute(post); - final int statusCode = response.getStatusLine().getStatusCode(); + final int statusCode = response.getStatusLine() + .getStatusCode(); final String responseString = getContent(); final String contentTypeInHeader = getContentTypeHeader(); assertThat(statusCode, equalTo(HttpStatus.SC_OK)); - assertTrue(responseString.contains("Content-Type: multipart/form-data;")); + // assertTrue(responseString.contains("Content-Type: multipart/form-data;")); assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;")); System.out.println(responseString); System.out.println("POST Content Type: " + contentTypeInHeader); @@ -179,7 +193,8 @@ public class HttpClientMultipartLiveTest { // UTIL final String getContent() throws IOException { - rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); + rd = new BufferedReader(new InputStreamReader(response.getEntity() + .getContent())); String body = ""; String content = ""; while ((body = rd.readLine()) != null) { @@ -189,7 +204,9 @@ public class HttpClientMultipartLiveTest { } final String getContentTypeHeader() throws IOException { - return post.getEntity().getContentType().toString(); + return post.getEntity() + .getContentType() + .toString(); } } diff --git a/httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java b/httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java index 278cdb3556..5dfecb85aa 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java @@ -1,11 +1,24 @@ package org.baeldung.httpclient; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.security.GeneralSecurityException; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLHandshakeException; + import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.ssl.*; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClientBuilder; @@ -15,14 +28,6 @@ import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.SSLContexts; import org.junit.Test; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLException; -import java.io.IOException; -import java.security.GeneralSecurityException; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; - /** * This test requires a localhost server over HTTPS
* It should only be manually run, not part of the automated build @@ -35,13 +40,15 @@ public class HttpsClientSslLiveTest { // tests - @Test(expected = SSLException.class) + @Test(expected = SSLHandshakeException.class) public final void whenHttpsUrlIsConsumed_thenException() throws IOException { - final CloseableHttpClient httpClient = HttpClientBuilder.create().build(); + final CloseableHttpClient httpClient = HttpClientBuilder.create() + .build(); final HttpGet getMethod = new HttpGet(HOST_WITH_SSL); final HttpResponse response = httpClient.execute(getMethod); - assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); + assertThat(response.getStatusLine() + .getStatusCode(), equalTo(200)); } @SuppressWarnings("deprecation") @@ -57,7 +64,8 @@ public class HttpsClientSslLiveTest { final HttpGet getMethod = new HttpGet(HOST_WITH_SSL); final HttpResponse response = httpClient.execute(getMethod); - assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); + assertThat(response.getStatusLine() + .getStatusCode(), equalTo(200)); httpClient.close(); } @@ -65,44 +73,62 @@ public class HttpsClientSslLiveTest { @Test public final void givenHttpClientAfter4_3_whenAcceptingAllCertificates_thenCanConsumeHttpsUriWithSelfSignedCertificate() throws IOException, GeneralSecurityException { final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true; - final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); + final SSLContext sslContext = SSLContexts.custom() + .loadTrustMaterial(null, acceptingTrustStrategy) + .build(); final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - final CloseableHttpClient httpClient = HttpClients.custom().setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER).setSSLSocketFactory(sslsf).build(); + final CloseableHttpClient httpClient = HttpClients.custom() + .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) + .setSSLSocketFactory(sslsf) + .build(); final HttpGet getMethod = new HttpGet(HOST_WITH_SSL); final HttpResponse response = httpClient.execute(getMethod); - assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); + assertThat(response.getStatusLine() + .getStatusCode(), equalTo(200)); httpClient.close(); } @Test public final void givenHttpClientPost4_3_whenAcceptingAllCertificates_thenCanConsumeHttpsUriWithSelfSignedCertificate() throws IOException, GeneralSecurityException { - final SSLContextBuilder builder = new SSLContextBuilder(); - builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); - final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build()); - final CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); + final SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy()) + .build(); + final NoopHostnameVerifier hostnameVerifier = new NoopHostnameVerifier(); + + final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); + final CloseableHttpClient httpClient = HttpClients.custom() + .setSSLHostnameVerifier(hostnameVerifier) + .setSSLSocketFactory(sslsf) + .build(); // new final HttpGet getMethod = new HttpGet(HOST_WITH_SSL); final HttpResponse response = httpClient.execute(getMethod); - assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); + assertThat(response.getStatusLine() + .getStatusCode(), equalTo(200)); + httpClient.close(); + } @Test public final void givenIgnoringCertificates_whenHttpsUrlIsConsumed_thenCorrect() throws Exception { - SSLContext sslContext = new SSLContextBuilder() - .loadTrustMaterial(null, (certificate, authType) -> true).build(); + final SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (certificate, authType) -> true) + .build(); - final CloseableHttpClient client = HttpClients.custom().setSSLContext(sslContext).setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); + final CloseableHttpClient client = HttpClients.custom() + .setSSLContext(sslContext) + .setSSLHostnameVerifier(new NoopHostnameVerifier()) + .build(); final HttpGet httpGet = new HttpGet(HOST_WITH_SSL); httpGet.setHeader("Accept", "application/xml"); final HttpResponse response = client.execute(httpGet); - assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); + assertThat(response.getStatusLine() + .getStatusCode(), equalTo(200)); } } From a5978cf2593ded7b79f2d6f6b454ca74c85e1fab Mon Sep 17 00:00:00 2001 From: KevinGilmore Date: Wed, 11 Jan 2017 21:05:36 -0600 Subject: [PATCH 11/14] Create README.md --- jsoup/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 jsoup/README.md diff --git a/jsoup/README.md b/jsoup/README.md new file mode 100644 index 0000000000..8728cc7c4e --- /dev/null +++ b/jsoup/README.md @@ -0,0 +1,10 @@ +========= + +## jsoup Example Project + +### Relevant Articles: +- [Parsing HTML in Java with Jsoup](http://www.baeldung.com/java-with-jsoup) + +### Build the Project + +mvn clean install From 7df755545a310d46ab3c882ce6ca32fe13ed8a01 Mon Sep 17 00:00:00 2001 From: Tomasz Lelek Date: Thu, 12 Jan 2017 11:16:34 +0100 Subject: [PATCH 12/14] BAEL-586 guava multimap examples --- .../java/com/baeldung/guava/MultimapTest.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 guava19/src/test/java/com/baeldung/guava/MultimapTest.java diff --git a/guava19/src/test/java/com/baeldung/guava/MultimapTest.java b/guava19/src/test/java/com/baeldung/guava/MultimapTest.java new file mode 100644 index 0000000000..dbe47923bb --- /dev/null +++ b/guava19/src/test/java/com/baeldung/guava/MultimapTest.java @@ -0,0 +1,62 @@ +package com.baeldung.guava; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import org.junit.Test; + +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +public class MultimapTest { + + @Test + public void givenMap_whenAddTwoValuesFroSameKey_shouldOverridePreviousKey() { + //given + String key = "a-key"; + Map map = new LinkedHashMap<>(); + + //when + map.put(key, "firstValue"); + map.put(key, "secondValue"); + + //then + assertEquals(1, map.size()); + } + + @Test + public void givenMultiMap_whenAddTwoValuesFroSameKey_shouldHaveTwoEntriesInMap() { + //given + String key = "a-key"; + Multimap map = ArrayListMultimap.create(); + + //when + map.put(key, "firstValue"); + map.put(key, "secondValue"); + + //then + assertEquals(2, map.size()); + } + + @Test + public void givenMapOfListValues_whenAddTwoValuesFroSameKey_shouldHaveTwoElementInList() { + //given + String key = "a-key"; + Map> map = new LinkedHashMap<>(); + + //when + List values = map.get(key); + if(values == null){ + values = new LinkedList<>(); + values.add("firstValue"); + values.add("secondValue"); + } + map.put(key, values); + + //then + assertEquals(1, map.size()); + } +} From 06ceb4d87c05adcad8551f9cf0037bc4b3a0c32f Mon Sep 17 00:00:00 2001 From: Saptarshi Basu Date: Thu, 12 Jan 2017 19:25:18 +0530 Subject: [PATCH 13/14] JAX-RS API using Jersey [BAEL-558] (#956) * WatchService vs. Apache Commons IO Mnitoring * Indentation fixed * Indentation fixed * JAX-RS API using Jersey [BAEL-558] * JAX-RS API using Jersey [BAEL-558] * Modifications made to remove xml * applicationContext.xml removed * All try catch moved to ExceptionMapper * fixes * review comments incorporated * module renamed --- pom.xml | 1 + spring-jersey/.gitignore | 13 ++ spring-jersey/README.md | 3 + spring-jersey/pom.xml | 210 ++++++++++++++++++ .../server/config/ApplicationInitializer.java | 22 ++ .../baeldung/server/config/RestConfig.java | 19 ++ .../AlreadyExistsExceptionHandler.java | 12 + .../exception/EmployeeAlreadyExists.java | 5 + .../server/exception/EmployeeNotFound.java | 5 + .../exception/NotFoundExceptionHandler.java | 12 + .../com/baeldung/server/model/Employee.java | 34 +++ .../server/repository/EmployeeRepository.java | 18 ++ .../repository/EmployeeRepositoryImpl.java | 65 ++++++ .../server/rest/EmployeeResource.java | 64 ++++++ spring-jersey/src/main/resources/logback.xml | 15 ++ .../baeldung/server/JerseyApiLiveTest.java | 91 ++++++++ 16 files changed, 589 insertions(+) create mode 100644 spring-jersey/.gitignore create mode 100644 spring-jersey/README.md create mode 100644 spring-jersey/pom.xml create mode 100644 spring-jersey/src/main/java/com/baeldung/server/config/ApplicationInitializer.java create mode 100644 spring-jersey/src/main/java/com/baeldung/server/config/RestConfig.java create mode 100644 spring-jersey/src/main/java/com/baeldung/server/exception/AlreadyExistsExceptionHandler.java create mode 100644 spring-jersey/src/main/java/com/baeldung/server/exception/EmployeeAlreadyExists.java create mode 100644 spring-jersey/src/main/java/com/baeldung/server/exception/EmployeeNotFound.java create mode 100644 spring-jersey/src/main/java/com/baeldung/server/exception/NotFoundExceptionHandler.java create mode 100644 spring-jersey/src/main/java/com/baeldung/server/model/Employee.java create mode 100644 spring-jersey/src/main/java/com/baeldung/server/repository/EmployeeRepository.java create mode 100644 spring-jersey/src/main/java/com/baeldung/server/repository/EmployeeRepositoryImpl.java create mode 100644 spring-jersey/src/main/java/com/baeldung/server/rest/EmployeeResource.java create mode 100644 spring-jersey/src/main/resources/logback.xml create mode 100644 spring-jersey/src/test/java/com/baeldung/server/JerseyApiLiveTest.java diff --git a/pom.xml b/pom.xml index c590183137..0b0351f462 100644 --- a/pom.xml +++ b/pom.xml @@ -117,6 +117,7 @@ spring-hibernate3 spring-hibernate4 spring-integration + spring-jersey spring-jms spring-jooq spring-jpa diff --git a/spring-jersey/.gitignore b/spring-jersey/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/spring-jersey/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-jersey/README.md b/spring-jersey/README.md new file mode 100644 index 0000000000..2767ceb9a7 --- /dev/null +++ b/spring-jersey/README.md @@ -0,0 +1,3 @@ +========= + +## REST API with Jersey & Spring Example Project diff --git a/spring-jersey/pom.xml b/spring-jersey/pom.xml new file mode 100644 index 0000000000..00d67febec --- /dev/null +++ b/spring-jersey/pom.xml @@ -0,0 +1,210 @@ + + + 4.0.0 + + com.baeldung + jersey-api + 0.1-SNAPSHOT + war + + + 2.25 + 1.7.22 + 1.1.8 + 4.12 + 3.0.0 + 2.19.1 + 1.6.1 + 4.12 + 4.4.5 + 4.5.2 + 3.1.0 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + maven-war-plugin + ${maven-war-plugin.version} + + false + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} + + true + + jetty8x + embedded + + + + 8082 + + + + + + + + + + + + + org.glassfish.jersey.core + jersey-server + ${jersey.version} + + + org.glassfish.jersey.containers + jersey-container-servlet + ${jersey.version} + + + org.glassfish.jersey.media + jersey-media-json-jackson + ${jersey.version} + + + + javax.servlet + javax.servlet-api + ${servlet-api-version} + provided + + + + + org.glassfish.jersey.ext + jersey-spring3 + ${jersey.version} + + + commons-logging + commons-logging + + + + + + org.slf4j + jcl-over-slf4j + ${jcl.slf4j.version} + + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + test + + + + org.apache.httpcomponents + httpcore + ${httpcore.version} + test + + + + + + junit + junit + ${junit.version} + test + + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*IntegrationTest.java + + + **/*LiveTest.java + + + + + + + json + + + + + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} + + false + + + + start-server + pre-integration-test + + start + + + + stop-server + post-integration-test + + stop + + + + + + + + + \ No newline at end of file diff --git a/spring-jersey/src/main/java/com/baeldung/server/config/ApplicationInitializer.java b/spring-jersey/src/main/java/com/baeldung/server/config/ApplicationInitializer.java new file mode 100644 index 0000000000..d91d4d5f38 --- /dev/null +++ b/spring-jersey/src/main/java/com/baeldung/server/config/ApplicationInitializer.java @@ -0,0 +1,22 @@ +package com.baeldung.server.config; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.web.WebApplicationInitializer; +import org.springframework.web.context.ContextLoaderListener; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; + +@Order(Ordered.HIGHEST_PRECEDENCE) +public class ApplicationInitializer implements WebApplicationInitializer { + + @Override + public void onStartup(ServletContext servletContext) throws ServletException { + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + servletContext.addListener(new ContextLoaderListener(context)); + servletContext.setInitParameter("contextConfigLocation", "com.baeldung.server"); + } + +} diff --git a/spring-jersey/src/main/java/com/baeldung/server/config/RestConfig.java b/spring-jersey/src/main/java/com/baeldung/server/config/RestConfig.java new file mode 100644 index 0000000000..34d8948f59 --- /dev/null +++ b/spring-jersey/src/main/java/com/baeldung/server/config/RestConfig.java @@ -0,0 +1,19 @@ +package com.baeldung.server.config; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +import com.baeldung.server.exception.AlreadyExistsExceptionHandler; +import com.baeldung.server.exception.NotFoundExceptionHandler; +import com.baeldung.server.rest.EmployeeResource; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +@ApplicationPath("/resources") +public class RestConfig extends Application { + public Set> getClasses() { + return new HashSet>(Arrays.asList(EmployeeResource.class, NotFoundExceptionHandler.class, AlreadyExistsExceptionHandler.class)); + } +} \ No newline at end of file diff --git a/spring-jersey/src/main/java/com/baeldung/server/exception/AlreadyExistsExceptionHandler.java b/spring-jersey/src/main/java/com/baeldung/server/exception/AlreadyExistsExceptionHandler.java new file mode 100644 index 0000000000..4603372807 --- /dev/null +++ b/spring-jersey/src/main/java/com/baeldung/server/exception/AlreadyExistsExceptionHandler.java @@ -0,0 +1,12 @@ +package com.baeldung.server.exception; + +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + +@Provider +public class AlreadyExistsExceptionHandler implements ExceptionMapper { + public Response toResponse(EmployeeAlreadyExists ex) { + return Response.status(Response.Status.CONFLICT.getStatusCode()).build(); + } +} diff --git a/spring-jersey/src/main/java/com/baeldung/server/exception/EmployeeAlreadyExists.java b/spring-jersey/src/main/java/com/baeldung/server/exception/EmployeeAlreadyExists.java new file mode 100644 index 0000000000..827e4bf1e7 --- /dev/null +++ b/spring-jersey/src/main/java/com/baeldung/server/exception/EmployeeAlreadyExists.java @@ -0,0 +1,5 @@ +package com.baeldung.server.exception; + +public class EmployeeAlreadyExists extends RuntimeException { + +} diff --git a/spring-jersey/src/main/java/com/baeldung/server/exception/EmployeeNotFound.java b/spring-jersey/src/main/java/com/baeldung/server/exception/EmployeeNotFound.java new file mode 100644 index 0000000000..f205b5dfae --- /dev/null +++ b/spring-jersey/src/main/java/com/baeldung/server/exception/EmployeeNotFound.java @@ -0,0 +1,5 @@ +package com.baeldung.server.exception; + +public class EmployeeNotFound extends RuntimeException { + +} diff --git a/spring-jersey/src/main/java/com/baeldung/server/exception/NotFoundExceptionHandler.java b/spring-jersey/src/main/java/com/baeldung/server/exception/NotFoundExceptionHandler.java new file mode 100644 index 0000000000..5de9b53c30 --- /dev/null +++ b/spring-jersey/src/main/java/com/baeldung/server/exception/NotFoundExceptionHandler.java @@ -0,0 +1,12 @@ +package com.baeldung.server.exception; + +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + +@Provider +public class NotFoundExceptionHandler implements ExceptionMapper { + public Response toResponse(EmployeeNotFound ex) { + return Response.status(Response.Status.NOT_FOUND).build(); + } +} diff --git a/spring-jersey/src/main/java/com/baeldung/server/model/Employee.java b/spring-jersey/src/main/java/com/baeldung/server/model/Employee.java new file mode 100644 index 0000000000..1801134f68 --- /dev/null +++ b/spring-jersey/src/main/java/com/baeldung/server/model/Employee.java @@ -0,0 +1,34 @@ +package com.baeldung.server.model; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class Employee { + private int id; + private String firstName; + + public Employee() { + + } + + public Employee(int id, String firstName) { + this.id = id; + this.firstName = firstName; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } +} diff --git a/spring-jersey/src/main/java/com/baeldung/server/repository/EmployeeRepository.java b/spring-jersey/src/main/java/com/baeldung/server/repository/EmployeeRepository.java new file mode 100644 index 0000000000..15132cd618 --- /dev/null +++ b/spring-jersey/src/main/java/com/baeldung/server/repository/EmployeeRepository.java @@ -0,0 +1,18 @@ +package com.baeldung.server.repository; + +import java.util.List; + +import com.baeldung.server.model.Employee; + +public interface EmployeeRepository { + + public List getAllEmployees(); + + public Employee getEmployee(int id); + + public void updateEmployee(Employee employee, int id); + + public void deleteEmployee(int id); + + public void addEmployee(Employee employee); +} diff --git a/spring-jersey/src/main/java/com/baeldung/server/repository/EmployeeRepositoryImpl.java b/spring-jersey/src/main/java/com/baeldung/server/repository/EmployeeRepositoryImpl.java new file mode 100644 index 0000000000..8e61e1395b --- /dev/null +++ b/spring-jersey/src/main/java/com/baeldung/server/repository/EmployeeRepositoryImpl.java @@ -0,0 +1,65 @@ +package com.baeldung.server.repository; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.stereotype.Component; + +import com.baeldung.server.exception.EmployeeAlreadyExists; +import com.baeldung.server.exception.EmployeeNotFound; +import com.baeldung.server.model.Employee; + +@Component +public class EmployeeRepositoryImpl implements EmployeeRepository { + private List employeeList; + + public EmployeeRepositoryImpl() { + employeeList = new ArrayList(); + employeeList.add(new Employee(1, "Jane")); + employeeList.add(new Employee(2, "Jack")); + employeeList.add(new Employee(3, "George")); + } + + public List getAllEmployees() { + return employeeList; + } + + public Employee getEmployee(int id) { + for (Employee emp : employeeList) { + if (emp.getId() == id) { + return emp; + } + } + throw new EmployeeNotFound(); + } + + public void updateEmployee(Employee employee, int id) { + for (Employee emp : employeeList) { + if (emp.getId() == id) { + emp.setId(employee.getId()); + emp.setFirstName(employee.getFirstName()); + return; + } + } + throw new EmployeeNotFound(); + } + + public void deleteEmployee(int id) { + for (Employee emp : employeeList) { + if (emp.getId() == id) { + employeeList.remove(emp); + return; + } + } + throw new EmployeeNotFound(); + } + + public void addEmployee(Employee employee) { + for (Employee emp : employeeList) { + if (emp.getId() == employee.getId()) { + throw new EmployeeAlreadyExists(); + } + } + employeeList.add(employee); + } +} diff --git a/spring-jersey/src/main/java/com/baeldung/server/rest/EmployeeResource.java b/spring-jersey/src/main/java/com/baeldung/server/rest/EmployeeResource.java new file mode 100644 index 0000000000..2301f3eaf3 --- /dev/null +++ b/spring-jersey/src/main/java/com/baeldung/server/rest/EmployeeResource.java @@ -0,0 +1,64 @@ +package com.baeldung.server.rest; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.baeldung.server.model.Employee; +import com.baeldung.server.repository.EmployeeRepository; + +@Path("/employees") +public class EmployeeResource { + + @Autowired + private EmployeeRepository employeeRepository; + + @GET + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + public List getAllEmployees() { + return employeeRepository.getAllEmployees(); + } + + @GET + @Path("/{id}") + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + public Employee getEmployee(@PathParam("id") int id) { + return employeeRepository.getEmployee(id); + } + + @PUT + @Path("/{id}") + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + public Response updateEmployee(Employee employee, @PathParam("id") int id) { + employeeRepository.updateEmployee(employee, id); + return Response.status(Response.Status.OK.getStatusCode()).build(); + } + + @DELETE + @Path("/{id}") + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + public Response deleteEmployee(@PathParam("id") int id) { + employeeRepository.deleteEmployee(id); + return Response.status(Response.Status.OK.getStatusCode()).build(); + } + + @POST + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + public Response addEmployee(Employee employee, @Context UriInfo uriInfo) { + employeeRepository.addEmployee(new Employee(employee.getId(), employee.getFirstName())); + return Response.status(Response.Status.CREATED.getStatusCode()).header("Location", String.format("%s/%s", uriInfo.getAbsolutePath().toString(), employee.getId())).build(); + } +} diff --git a/spring-jersey/src/main/resources/logback.xml b/spring-jersey/src/main/resources/logback.xml new file mode 100644 index 0000000000..788096686a --- /dev/null +++ b/spring-jersey/src/main/resources/logback.xml @@ -0,0 +1,15 @@ + + + + + web - %date [%thread] %-5level %logger{36} - + %message%n + + + + + + + + + \ No newline at end of file diff --git a/spring-jersey/src/test/java/com/baeldung/server/JerseyApiLiveTest.java b/spring-jersey/src/test/java/com/baeldung/server/JerseyApiLiveTest.java new file mode 100644 index 0000000000..80c4e94b50 --- /dev/null +++ b/spring-jersey/src/test/java/com/baeldung/server/JerseyApiLiveTest.java @@ -0,0 +1,91 @@ +package com.baeldung.server; + +import java.io.IOException; + +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClientBuilder; +import org.junit.Test; + +import com.baeldung.server.model.Employee; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JerseyApiLiveTest { + + private static final String SERVICE_URL = "http://localhost:8082/jersey-api/resources/employees"; + + @Test + public void givenGetAllEmployees_whenCorrectRequest_thenResponseCodeSuccess() throws ClientProtocolException, IOException { + final HttpUriRequest request = new HttpGet(SERVICE_URL); + + final HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request); + + assert(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK); + } + + @Test + public void givenGetEmployee_whenEmployeeExists_thenResponseCodeSuccess() throws ClientProtocolException, IOException { + final HttpUriRequest request = new HttpGet(SERVICE_URL + "/1"); + + final HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request); + + assert(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK); + } + + @Test + public void givenGetEmployee_whenEmployeeDoesNotExist_thenResponseCodeNotFound() throws ClientProtocolException, IOException { + final HttpUriRequest request = new HttpGet(SERVICE_URL + "/1000"); + + final HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request); + + assert(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND); + } + + @Test + public void givenGetEmployee_whenJsonRequested_thenCorrectDataRetrieved() throws ClientProtocolException, IOException { + final HttpUriRequest request = new HttpGet(SERVICE_URL + "/1"); + + request.setHeader("Accept", "application/json"); + final HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request); + ObjectMapper mapper = new ObjectMapper(); + Employee emp = mapper.readValue(httpResponse.getEntity().getContent(), Employee.class); + + assert(emp.getFirstName().equals("Jane")); + } + + @Test + public void givenAddEmployee_whenJsonRequestSent_thenResponseCodeCreated() throws ClientProtocolException, IOException { + final HttpPost request = new HttpPost(SERVICE_URL); + + Employee emp = new Employee(5, "Johny"); + ObjectMapper mapper = new ObjectMapper(); + String empJson = mapper.writeValueAsString(emp); + StringEntity input = new StringEntity(empJson); + input.setContentType("application/json"); + request.setEntity(input); + final HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request); + + assert(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED); + } + + @Test + public void givenAddEmployee_whenRequestForExistingObjectSent_thenResponseCodeConflict() throws ClientProtocolException, IOException { + final HttpPost request = new HttpPost(SERVICE_URL); + + Employee emp = new Employee(1, "Johny"); + ObjectMapper mapper = new ObjectMapper(); + String empJson = mapper.writeValueAsString(emp); + StringEntity input = new StringEntity(empJson); + input.setContentType("application/json"); + request.setEntity(input); + final HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request); + + assert(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_CONFLICT); + } + +} \ No newline at end of file From 91fb87c06dc2fb406c8d8d0b14351c55095fdf96 Mon Sep 17 00:00:00 2001 From: Tomasz Lelek Date: Thu, 12 Jan 2017 18:41:04 +0100 Subject: [PATCH 14/14] BAEL-586 rename tests according to pr review --- guava19/src/test/java/com/baeldung/guava/MultimapTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/guava19/src/test/java/com/baeldung/guava/MultimapTest.java b/guava19/src/test/java/com/baeldung/guava/MultimapTest.java index dbe47923bb..c984ab1e4b 100644 --- a/guava19/src/test/java/com/baeldung/guava/MultimapTest.java +++ b/guava19/src/test/java/com/baeldung/guava/MultimapTest.java @@ -14,7 +14,7 @@ import static org.junit.Assert.assertEquals; public class MultimapTest { @Test - public void givenMap_whenAddTwoValuesFroSameKey_shouldOverridePreviousKey() { + public void givenMap_whenAddTwoValuesForSameKey_shouldOverridePreviousKey() { //given String key = "a-key"; Map map = new LinkedHashMap<>(); @@ -28,7 +28,7 @@ public class MultimapTest { } @Test - public void givenMultiMap_whenAddTwoValuesFroSameKey_shouldHaveTwoEntriesInMap() { + public void givenMultiMap_whenAddTwoValuesForSameKey_shouldHaveTwoEntriesInMap() { //given String key = "a-key"; Multimap map = ArrayListMultimap.create(); @@ -42,7 +42,7 @@ public class MultimapTest { } @Test - public void givenMapOfListValues_whenAddTwoValuesFroSameKey_shouldHaveTwoElementInList() { + public void givenMapOfListValues_whenAddTwoValuesForSameKey_shouldHaveTwoElementsInList() { //given String key = "a-key"; Map> map = new LinkedHashMap<>();