diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..9c5cdb8f2d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "testgitrepo"] + path = testgitrepo + url = /home/prd/Development/projects/idea/tutorials/spring-boot/src/main/resources/testgitrepo/ diff --git a/annotations/annotation-processing/pom.xml b/annotations/annotation-processing/pom.xml new file mode 100644 index 0000000000..6d07394b87 --- /dev/null +++ b/annotations/annotation-processing/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + + com.baeldung + 1.0.0-SNAPSHOT + annotations + ../ + + + annotation-processing + + + 1.0-rc2 + 3.5.1 + + + + + + com.google.auto.service + auto-service + ${auto-service.version} + provided + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + + + + + \ No newline at end of file diff --git a/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProcessor.java b/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProcessor.java new file mode 100644 index 0000000000..0883e108e7 --- /dev/null +++ b/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProcessor.java @@ -0,0 +1,132 @@ +package com.baeldung.annotation.processor; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.ExecutableType; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; + +import com.google.auto.service.AutoService; + +@SupportedAnnotationTypes("com.baeldung.annotation.processor.BuilderProperty") +@SupportedSourceVersion(SourceVersion.RELEASE_8) +@AutoService(Processor.class) +public class BuilderProcessor extends AbstractProcessor { + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + for (TypeElement annotation : annotations) { + + Set annotatedElements = roundEnv.getElementsAnnotatedWith(annotation); + + Map> annotatedMethods = annotatedElements.stream() + .collect(Collectors.partitioningBy(element -> + ((ExecutableType) element.asType()).getParameterTypes().size() == 1 + && element.getSimpleName().toString().startsWith("set"))); + + List setters = annotatedMethods.get(true); + List otherMethods = annotatedMethods.get(false); + + otherMethods.forEach(element -> + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, + "@BuilderProperty must be applied to a setXxx method with a single argument", element)); + + if (setters.isEmpty()) { + continue; + } + + String className = ((TypeElement) setters.get(0).getEnclosingElement()).getQualifiedName().toString(); + + Map setterMap = setters.stream().collect(Collectors.toMap( + setter -> setter.getSimpleName().toString(), + setter -> ((ExecutableType) setter.asType()) + .getParameterTypes().get(0).toString() + )); + + try { + writeBuilderFile(className, setterMap); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + return true; + } + + private void writeBuilderFile(String className, Map setterMap) throws IOException { + + String packageName = null; + int lastDot = className.lastIndexOf('.'); + if (lastDot > 0) { + packageName = className.substring(0, lastDot); + } + + String simpleClassName = className.substring(lastDot + 1); + String builderClassName = className + "Builder"; + String builderSimpleClassName = builderClassName.substring(lastDot + 1); + + JavaFileObject builderFile = processingEnv.getFiler().createSourceFile(builderClassName); + try (PrintWriter out = new PrintWriter(builderFile.openWriter())) { + + if (packageName != null) { + out.print("package "); + out.print(packageName); + out.println(";"); + out.println(); + } + + out.print("public class "); + out.print(builderSimpleClassName); + out.println(" {"); + out.println(); + + out.print(" private "); + out.print(simpleClassName); + out.print(" object = new "); + out.print(simpleClassName); + out.println("();"); + out.println(); + + out.print(" public "); + out.print(simpleClassName); + out.println(" build() {"); + out.println(" return object;"); + out.println(" }"); + out.println(); + + setterMap.entrySet().forEach(setter -> { + String methodName = setter.getKey(); + String argumentType = setter.getValue(); + + out.print(" public "); + out.print(builderSimpleClassName); + out.print(" "); + out.print(methodName); + + out.print("("); + + out.print(argumentType); + out.println(" value) {"); + out.print(" object."); + out.print(methodName); + out.println("(value);"); + out.println(" return this;"); + out.println(" }"); + out.println(); + }); + + out.println("}"); + + } + } + +} diff --git a/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProperty.java b/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProperty.java new file mode 100644 index 0000000000..84fcc73850 --- /dev/null +++ b/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProperty.java @@ -0,0 +1,8 @@ +package com.baeldung.annotation.processor; + +import java.lang.annotation.*; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface BuilderProperty { +} diff --git a/annotations/annotation-user/pom.xml b/annotations/annotation-user/pom.xml new file mode 100644 index 0000000000..f76f691f93 --- /dev/null +++ b/annotations/annotation-user/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + + annotations + com.baeldung + 1.0.0-SNAPSHOT + ../ + + + annotation-user + + + + + com.baeldung + annotation-processing + ${project.parent.version} + + + + junit + junit + 4.12 + test + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + + + + + \ No newline at end of file diff --git a/annotations/annotation-user/src/main/java/com/baeldung/annotation/Person.java b/annotations/annotation-user/src/main/java/com/baeldung/annotation/Person.java new file mode 100644 index 0000000000..23787ba4f4 --- /dev/null +++ b/annotations/annotation-user/src/main/java/com/baeldung/annotation/Person.java @@ -0,0 +1,29 @@ +package com.baeldung.annotation; + +import com.baeldung.annotation.processor.BuilderProperty; + +public class Person { + + private int age; + + private String name; + + public int getAge() { + return age; + } + + @BuilderProperty + public void setAge(int age) { + this.age = age; + } + + public String getName() { + return name; + } + + @BuilderProperty + public void setName(String name) { + this.name = name; + } + +} diff --git a/annotations/annotation-user/src/test/java/com/baeldung/annotation/PersonBuilderTest.java b/annotations/annotation-user/src/test/java/com/baeldung/annotation/PersonBuilderTest.java new file mode 100644 index 0000000000..72f9ac8bc7 --- /dev/null +++ b/annotations/annotation-user/src/test/java/com/baeldung/annotation/PersonBuilderTest.java @@ -0,0 +1,22 @@ +package com.baeldung.annotation; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class PersonBuilderTest { + + @Test + public void whenBuildPersonWithBuilder_thenObjectHasPropertyValues() { + + Person person = new PersonBuilder() + .setAge(25) + .setName("John") + .build(); + + assertEquals(25, person.getAge()); + assertEquals("John", person.getName()); + + } + +} diff --git a/annotations/pom.xml b/annotations/pom.xml new file mode 100644 index 0000000000..f691674cf1 --- /dev/null +++ b/annotations/pom.xml @@ -0,0 +1,20 @@ + + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + 4.0.0 + + annotations + pom + + + annotation-processing + annotation-user + + + \ No newline at end of file diff --git a/annotations/readme.md b/annotations/readme.md new file mode 100644 index 0000000000..2b052803e6 --- /dev/null +++ b/annotations/readme.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Java Annotation Processing and Creating a Builder](http://www.baeldung.com/java-annotation-processing-builder) diff --git a/apache-cxf/cxf-introduction/README.md b/apache-cxf/cxf-introduction/README.md new file mode 100644 index 0000000000..9a076524b7 --- /dev/null +++ b/apache-cxf/cxf-introduction/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Introduction to Apache CXF](http://www.baeldung.com/introduction-to-apache-cxf) diff --git a/apache-cxf/cxf-introduction/pom.xml b/apache-cxf/cxf-introduction/pom.xml index 232a4f0089..0902bd690e 100644 --- a/apache-cxf/cxf-introduction/pom.xml +++ b/apache-cxf/cxf-introduction/pom.xml @@ -11,6 +11,7 @@ 3.1.6 + 2.19.1 @@ -26,7 +27,7 @@ 2.19.1 - **/StudentTest.java + **/*LiveTest.java @@ -44,4 +45,5 @@ ${cxf.version} + diff --git a/apache-cxf/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentTest.java b/apache-cxf/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentLiveTest.java similarity index 65% rename from apache-cxf/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentTest.java rename to apache-cxf/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentLiveTest.java index e1e5b60ec3..60fc0a10e7 100644 --- a/apache-cxf/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentTest.java +++ b/apache-cxf/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentLiveTest.java @@ -2,20 +2,16 @@ package com.baeldung.cxf.introduction; import static org.junit.Assert.assertEquals; -import org.junit.Before; -import org.junit.Test; - import java.util.Map; import javax.xml.namespace.QName; import javax.xml.ws.Service; import javax.xml.ws.soap.SOAPBinding; -import com.baeldung.cxf.introduction.Baeldung; -import com.baeldung.cxf.introduction.Student; -import com.baeldung.cxf.introduction.StudentImpl; +import org.junit.Before; +import org.junit.Test; -public class StudentTest { +public class StudentLiveTest { private static QName SERVICE_NAME = new QName("http://introduction.cxf.baeldung.com/", "Baeldung"); private static QName PORT_NAME = new QName("http://introduction.cxf.baeldung.com/", "BaeldungPort"); @@ -25,7 +21,7 @@ public class StudentTest { { service = Service.create(SERVICE_NAME); - String endpointAddress = "http://localhost:8080/baeldung"; + final String endpointAddress = "http://localhost:8080/baeldung"; service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress); } @@ -37,28 +33,28 @@ public class StudentTest { @Test public void whenUsingHelloMethod_thenCorrect() { - String endpointResponse = baeldungProxy.hello("Baeldung"); - String localResponse = baeldungImpl.hello("Baeldung"); + final String endpointResponse = baeldungProxy.hello("Baeldung"); + final String localResponse = baeldungImpl.hello("Baeldung"); assertEquals(localResponse, endpointResponse); } @Test public void whenUsingHelloStudentMethod_thenCorrect() { - Student student = new StudentImpl("John Doe"); - String endpointResponse = baeldungProxy.helloStudent(student); - String localResponse = baeldungImpl.helloStudent(student); + final Student student = new StudentImpl("John Doe"); + final String endpointResponse = baeldungProxy.helloStudent(student); + final String localResponse = baeldungImpl.helloStudent(student); assertEquals(localResponse, endpointResponse); } @Test public void usingGetStudentsMethod_thenCorrect() { - Student student1 = new StudentImpl("Adam"); + final Student student1 = new StudentImpl("Adam"); baeldungProxy.helloStudent(student1); - Student student2 = new StudentImpl("Eve"); + final Student student2 = new StudentImpl("Eve"); baeldungProxy.helloStudent(student2); - - Map students = baeldungProxy.getStudents(); + + final Map students = baeldungProxy.getStudents(); assertEquals("Adam", students.get(1).getName()); assertEquals("Eve", students.get(2).getName()); } diff --git a/apache-cxf/cxf-jaxrs-implementation/pom.xml b/apache-cxf/cxf-jaxrs-implementation/pom.xml new file mode 100644 index 0000000000..b3a81aef82 --- /dev/null +++ b/apache-cxf/cxf-jaxrs-implementation/pom.xml @@ -0,0 +1,55 @@ + + + + 4.0.0 + cxf-jaxrs-implementation + + com.baeldung + apache-cxf + 0.0.1-SNAPSHOT + + + UTF-8 + 3.1.7 + 4.5.2 + 2.19.1 + + + + + org.codehaus.mojo + exec-maven-plugin + + com.baeldung.cxf.jaxrs.implementation.RestfulServer + + + + maven-surefire-plugin + 2.19.1 + + + **/*LiveTest.java + + + + + + + + org.apache.cxf + cxf-rt-frontend-jaxrs + ${cxf.version} + + + org.apache.cxf + cxf-rt-transports-http-jetty + ${cxf.version} + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Course.java b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Course.java new file mode 100644 index 0000000000..dba9b9c661 --- /dev/null +++ b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Course.java @@ -0,0 +1,86 @@ +package com.baeldung.cxf.jaxrs.implementation; + +import javax.ws.rs.*; +import javax.ws.rs.core.Response; +import javax.xml.bind.annotation.XmlRootElement; + +import java.util.ArrayList; +import java.util.List; + +@XmlRootElement(name = "Course") +public class Course { + private int id; + private String name; + private List students = new ArrayList<>(); + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getStudents() { + return students; + } + + public void setStudents(List students) { + this.students = students; + } + + @GET + @Path("{studentId}") + public Student getStudent(@PathParam("studentId") int studentId) { + return findById(studentId); + } + + @POST + public Response createStudent(Student student) { + for (Student element : students) { + if (element.getId() == student.getId()) { + return Response.status(Response.Status.CONFLICT).build(); + } + } + students.add(student); + return Response.ok(student).build(); + } + + @DELETE + @Path("{studentId}") + public Response deleteStudent(@PathParam("studentId") int studentId) { + Student student = findById(studentId); + if (student == null) { + return Response.status(Response.Status.NOT_FOUND).build(); + } + students.remove(student); + return Response.ok().build(); + } + + private Student findById(int id) { + for (Student student : students) { + if (student.getId() == id) { + return student; + } + } + return null; + } + + @Override + public int hashCode() { + return id + name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return (obj instanceof Course) && (id == ((Course) obj).getId()) && (name.equals(((Course) obj).getName())); + } +} \ No newline at end of file diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/CourseRepository.java b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/CourseRepository.java new file mode 100644 index 0000000000..a2fd6be435 --- /dev/null +++ b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/CourseRepository.java @@ -0,0 +1,72 @@ +package com.baeldung.cxf.jaxrs.implementation; + +import javax.ws.rs.*; +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Path("baeldung") +@Produces("text/xml") +public class CourseRepository { + private Map courses = new HashMap<>(); + + { + Student student1 = new Student(); + Student student2 = new Student(); + student1.setId(1); + student1.setName("Student A"); + student2.setId(2); + student2.setName("Student B"); + + List course1Students = new ArrayList<>(); + course1Students.add(student1); + course1Students.add(student2); + + Course course1 = new Course(); + Course course2 = new Course(); + course1.setId(1); + course1.setName("REST with Spring"); + course1.setStudents(course1Students); + course2.setId(2); + course2.setName("Learn Spring Security"); + + courses.put(1, course1); + courses.put(2, course2); + } + + @GET + @Path("courses/{courseId}") + public Course getCourse(@PathParam("courseId") int courseId) { + return findById(courseId); + } + + @PUT + @Path("courses/{courseId}") + public Response updateCourse(@PathParam("courseId") int courseId, Course course) { + Course existingCourse = findById(courseId); + if (existingCourse == null) { + return Response.status(Response.Status.NOT_FOUND).build(); + } + if (existingCourse.equals(course)) { + return Response.notModified().build(); + } + courses.put(courseId, course); + return Response.ok().build(); + } + + @Path("courses/{courseId}/students") + public Course pathToStudent(@PathParam("courseId") int courseId) { + return findById(courseId); + } + + private Course findById(int id) { + for (Map.Entry course : courses.entrySet()) { + if (course.getKey() == id) { + return course.getValue(); + } + } + return null; + } +} diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/RestfulServer.java b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/RestfulServer.java new file mode 100644 index 0000000000..d3ed2eb70e --- /dev/null +++ b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/RestfulServer.java @@ -0,0 +1,21 @@ +package com.baeldung.cxf.jaxrs.implementation; + +import org.apache.cxf.endpoint.Server; +import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; +import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider; + +public class RestfulServer { + public static void main(String args[]) throws Exception { + JAXRSServerFactoryBean factoryBean = new JAXRSServerFactoryBean(); + factoryBean.setResourceClasses(CourseRepository.class); + factoryBean.setResourceProvider(new SingletonResourceProvider(new CourseRepository())); + factoryBean.setAddress("http://localhost:8080/"); + Server server = factoryBean.create(); + + System.out.println("Server ready..."); + Thread.sleep(60 * 1000); + System.out.println("Server exiting"); + server.destroy(); + System.exit(0); + } +} diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Student.java b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Student.java new file mode 100644 index 0000000000..bd3dad0f5e --- /dev/null +++ b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Student.java @@ -0,0 +1,35 @@ +package com.baeldung.cxf.jaxrs.implementation; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "Student") +public class Student { + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + return id + name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return (obj instanceof Student) && (id == ((Student) obj).getId()) && (name.equals(((Student) obj).getName())); + } +} \ No newline at end of file diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/changed_course.xml b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/changed_course.xml new file mode 100644 index 0000000000..097cf2ce58 --- /dev/null +++ b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/changed_course.xml @@ -0,0 +1,4 @@ + + 2 + Apache CXF Support for RESTful + \ No newline at end of file diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/conflict_student.xml b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/conflict_student.xml new file mode 100644 index 0000000000..7d083dbdc9 --- /dev/null +++ b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/conflict_student.xml @@ -0,0 +1,4 @@ + + 2 + Student B + \ No newline at end of file diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/created_student.xml b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/created_student.xml new file mode 100644 index 0000000000..068c9dae4b --- /dev/null +++ b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/created_student.xml @@ -0,0 +1,4 @@ + + 3 + Student C + \ No newline at end of file diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/non_existent_course.xml b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/non_existent_course.xml new file mode 100644 index 0000000000..465c337745 --- /dev/null +++ b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/non_existent_course.xml @@ -0,0 +1,4 @@ + + 3 + Apache CXF Support for RESTful + \ No newline at end of file diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/unchanged_course.xml b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/unchanged_course.xml new file mode 100644 index 0000000000..5936fdc094 --- /dev/null +++ b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/unchanged_course.xml @@ -0,0 +1,4 @@ + + 1 + REST with Spring + \ No newline at end of file diff --git a/apache-cxf/cxf-jaxrs-implementation/src/test/java/com/baeldung/cxf/jaxrs/implementation/ServiceLiveTest.java b/apache-cxf/cxf-jaxrs-implementation/src/test/java/com/baeldung/cxf/jaxrs/implementation/ServiceLiveTest.java new file mode 100644 index 0000000000..29c34ae16b --- /dev/null +++ b/apache-cxf/cxf-jaxrs-implementation/src/test/java/com/baeldung/cxf/jaxrs/implementation/ServiceLiveTest.java @@ -0,0 +1,130 @@ +package com.baeldung.cxf.jaxrs.implementation; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; + +import javax.xml.bind.JAXB; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.entity.InputStreamEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class ServiceLiveTest { + private static final String BASE_URL = "http://localhost:8080/baeldung/courses/"; + private static CloseableHttpClient client; + + @BeforeClass + public static void createClient() { + client = HttpClients.createDefault(); + } + + @AfterClass + public static void closeClient() throws IOException { + client.close(); + } + + @Test + public void whenUpdateNonExistentCourse_thenReceiveNotFoundResponse() throws IOException { + final HttpPut httpPut = new HttpPut(BASE_URL + "3"); + final InputStream resourceStream = this.getClass().getClassLoader().getResourceAsStream("non_existent_course.xml"); + httpPut.setEntity(new InputStreamEntity(resourceStream)); + httpPut.setHeader("Content-Type", "text/xml"); + + final HttpResponse response = client.execute(httpPut); + assertEquals(404, response.getStatusLine().getStatusCode()); + } + + @Test + public void whenUpdateUnchangedCourse_thenReceiveNotModifiedResponse() throws IOException { + final HttpPut httpPut = new HttpPut(BASE_URL + "1"); + final InputStream resourceStream = this.getClass().getClassLoader().getResourceAsStream("unchanged_course.xml"); + httpPut.setEntity(new InputStreamEntity(resourceStream)); + httpPut.setHeader("Content-Type", "text/xml"); + + final HttpResponse response = client.execute(httpPut); + assertEquals(304, response.getStatusLine().getStatusCode()); + } + + @Test + public void whenUpdateValidCourse_thenReceiveOKResponse() throws IOException { + final HttpPut httpPut = new HttpPut(BASE_URL + "2"); + final InputStream resourceStream = this.getClass().getClassLoader().getResourceAsStream("changed_course.xml"); + httpPut.setEntity(new InputStreamEntity(resourceStream)); + httpPut.setHeader("Content-Type", "text/xml"); + + final HttpResponse response = client.execute(httpPut); + assertEquals(200, response.getStatusLine().getStatusCode()); + + final Course course = getCourse(2); + assertEquals(2, course.getId()); + assertEquals("Apache CXF Support for RESTful", course.getName()); + } + + @Test + public void whenCreateConflictStudent_thenReceiveConflictResponse() throws IOException { + final HttpPost httpPost = new HttpPost(BASE_URL + "1/students"); + final InputStream resourceStream = this.getClass().getClassLoader().getResourceAsStream("conflict_student.xml"); + httpPost.setEntity(new InputStreamEntity(resourceStream)); + httpPost.setHeader("Content-Type", "text/xml"); + + final HttpResponse response = client.execute(httpPost); + assertEquals(409, response.getStatusLine().getStatusCode()); + } + + @Test + public void whenCreateValidStudent_thenReceiveOKResponse() throws IOException { + final HttpPost httpPost = new HttpPost(BASE_URL + "2/students"); + final InputStream resourceStream = this.getClass().getClassLoader().getResourceAsStream("created_student.xml"); + httpPost.setEntity(new InputStreamEntity(resourceStream)); + httpPost.setHeader("Content-Type", "text/xml"); + + final HttpResponse response = client.execute(httpPost); + assertEquals(200, response.getStatusLine().getStatusCode()); + + final Student student = getStudent(2, 3); + assertEquals(3, student.getId()); + assertEquals("Student C", student.getName()); + } + + @Test + public void whenDeleteInvalidStudent_thenReceiveNotFoundResponse() throws IOException { + final HttpDelete httpDelete = new HttpDelete(BASE_URL + "1/students/3"); + final HttpResponse response = client.execute(httpDelete); + assertEquals(404, response.getStatusLine().getStatusCode()); + } + + @Test + public void whenDeleteValidStudent_thenReceiveOKResponse() throws IOException { + final HttpDelete httpDelete = new HttpDelete(BASE_URL + "1/students/1"); + final HttpResponse response = client.execute(httpDelete); + assertEquals(200, response.getStatusLine().getStatusCode()); + + final Course course = getCourse(1); + assertEquals(1, course.getStudents().size()); + assertEquals(2, course.getStudents().get(0).getId()); + assertEquals("Student B", course.getStudents().get(0).getName()); + } + + private Course getCourse(int courseOrder) throws IOException { + final URL url = new URL(BASE_URL + courseOrder); + final InputStream input = url.openStream(); + return JAXB.unmarshal(new InputStreamReader(input), Course.class); + } + + private Student getStudent(int courseOrder, int studentOrder) throws IOException { + final URL url = new URL(BASE_URL + courseOrder + "/students/" + studentOrder); + final InputStream input = url.openStream(); + return JAXB.unmarshal(new InputStreamReader(input), Student.class); + } +} \ No newline at end of file diff --git a/apache-cxf/cxf-spring/pom.xml b/apache-cxf/cxf-spring/pom.xml index 85e68300f0..8f1dee965a 100644 --- a/apache-cxf/cxf-spring/pom.xml +++ b/apache-cxf/cxf-spring/pom.xml @@ -51,7 +51,7 @@ ${surefire.version} - StudentTest.java + **/*LiveTest.java @@ -60,7 +60,7 @@ - integration + live diff --git a/apache-cxf/cxf-spring/src/test/java/com/baeldung/cxf/spring/StudentTest.java b/apache-cxf/cxf-spring/src/test/java/com/baeldung/cxf/spring/StudentLiveTest.java similarity index 97% rename from apache-cxf/cxf-spring/src/test/java/com/baeldung/cxf/spring/StudentTest.java rename to apache-cxf/cxf-spring/src/test/java/com/baeldung/cxf/spring/StudentLiveTest.java index 7466944e04..80a8f6c3b8 100644 --- a/apache-cxf/cxf-spring/src/test/java/com/baeldung/cxf/spring/StudentTest.java +++ b/apache-cxf/cxf-spring/src/test/java/com/baeldung/cxf/spring/StudentLiveTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; -public class StudentTest { +public class StudentLiveTest { private ApplicationContext context = new AnnotationConfigApplicationContext(ClientConfiguration.class); private Baeldung baeldungProxy = (Baeldung) context.getBean("client"); diff --git a/apache-cxf/pom.xml b/apache-cxf/pom.xml index 022fc59f9b..af7949bb6c 100644 --- a/apache-cxf/pom.xml +++ b/apache-cxf/pom.xml @@ -8,6 +8,7 @@ cxf-introduction cxf-spring + cxf-jaxrs-implementation diff --git a/apache-fop/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch b/apache-fop/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch deleted file mode 100644 index 627021fb96..0000000000 --- a/apache-fop/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/apache-fop/pom.xml b/apache-fop/pom.xml index 658d567a90..949843a47e 100644 --- a/apache-fop/pom.xml +++ b/apache-fop/pom.xml @@ -97,6 +97,14 @@ 8.0.2 + + org.dbdoclet + herold + 6.1.0 + system + ${basedir}/src/test/resources/jars/herold.jar + + net.sf.jtidy jtidy @@ -132,7 +140,8 @@ ${maven-surefire-plugin.version} - **/*IntegrationTest.java + **/*IntegrationTest.java + **/*LiveTest.java @@ -141,6 +150,42 @@ + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*ManualTest.java + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + json + + + + + + + + 4.3.11.Final diff --git a/apache-fop/src/test/java/org/baeldung/java/ApacheFOPConvertHTMLTest.java b/apache-fop/src/test/java/org/baeldung/java/ApacheFOPConvertHTMLIntegrationTest.java similarity index 98% rename from apache-fop/src/test/java/org/baeldung/java/ApacheFOPConvertHTMLTest.java rename to apache-fop/src/test/java/org/baeldung/java/ApacheFOPConvertHTMLIntegrationTest.java index bde6868b39..99487c8fdf 100644 --- a/apache-fop/src/test/java/org/baeldung/java/ApacheFOPConvertHTMLTest.java +++ b/apache-fop/src/test/java/org/baeldung/java/ApacheFOPConvertHTMLIntegrationTest.java @@ -25,7 +25,7 @@ import org.junit.Test; import org.w3c.dom.Document; import org.w3c.tidy.Tidy; -public class ApacheFOPConvertHTMLTest { +public class ApacheFOPConvertHTMLIntegrationTest { private String inputFile = "src/test/resources/input.html"; private String style = "src/test/resources/xhtml2fo.xsl"; private String style1 = "src/test/resources/docbook-xsl/fo/docbook.xsl"; diff --git a/apache-fop/src/test/java/org/baeldung/java/ApacheFOPHeroldTest.java b/apache-fop/src/test/java/org/baeldung/java/ApacheFOPHeroldLiveTest.java similarity index 99% rename from apache-fop/src/test/java/org/baeldung/java/ApacheFOPHeroldTest.java rename to apache-fop/src/test/java/org/baeldung/java/ApacheFOPHeroldLiveTest.java index 5e3c2c472b..9e71cd9c16 100644 --- a/apache-fop/src/test/java/org/baeldung/java/ApacheFOPHeroldTest.java +++ b/apache-fop/src/test/java/org/baeldung/java/ApacheFOPHeroldLiveTest.java @@ -30,7 +30,7 @@ import org.dbdoclet.trafo.script.Script; import org.junit.Test; import org.w3c.dom.Document; -public class ApacheFOPHeroldTest { +public class ApacheFOPHeroldLiveTest { private String[] inputUrls = {// @formatter:off "http://www.baeldung.com/2011/10/20/bootstraping-a-web-application-with-spring-3-1-and-java-based-configuration-part-1/", "http://www.baeldung.com/2011/10/25/building-a-restful-web-service-with-spring-3-1-and-java-based-configuration-part-2/", diff --git a/assertj/README.md b/assertj/README.md new file mode 100644 index 0000000000..86eff05057 --- /dev/null +++ b/assertj/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: +- [AssertJ’s Java 8 Features](http://www.baeldung.com/assertJ-java-8-features) +- [AssertJ for Guava](http://www.baeldung.com/assertJ-for-guava) diff --git a/assertj/pom.xml b/assertj/pom.xml index 421afd40a5..df55ebba4b 100644 --- a/assertj/pom.xml +++ b/assertj/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung @@ -9,11 +8,18 @@ 1.0.0-SNAPSHOT + com.google.guava guava - 19.0 + ${guava.version} + + org.assertj + assertj-guava + 3.0.0 + + junit junit @@ -26,11 +32,7 @@ 3.5.1 test - - org.assertj - assertj-guava - 3.0.0 - + @@ -46,4 +48,9 @@ + + + 19.0 + + \ No newline at end of file diff --git a/autovalue-tutorial/pom.xml b/autovalue-tutorial/pom.xml deleted file mode 100644 index 37d595dce1..0000000000 --- a/autovalue-tutorial/pom.xml +++ /dev/null @@ -1,36 +0,0 @@ - - 4.0.0 - com.baeldung - autovalue-tutorial - 1.0 - AutoValue - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.3 - - 7 - 7 - - - - - - - com.google.auto.value - auto-value - 1.2 - - - - junit - junit - 4.3 - test - - - - diff --git a/autovalue/README.md b/autovalue/README.md new file mode 100644 index 0000000000..2385e82847 --- /dev/null +++ b/autovalue/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Introduction to AutoValue](http://www.baeldung.com/introduction-to-autovalue) diff --git a/autovalue/pom.xml b/autovalue/pom.xml new file mode 100644 index 0000000000..d1f8e825fc --- /dev/null +++ b/autovalue/pom.xml @@ -0,0 +1,37 @@ + + 4.0.0 + com.baeldung + autovalue-tutorial + 1.0 + AutoValue + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 7 + 7 + false + + + + + + + com.google.auto.value + auto-value + 1.2 + + + + junit + junit + 4.3 + test + + + + diff --git a/autovalue-tutorial/src/main/java/com/baeldung/autovalue/AutoValueMoney.java b/autovalue/src/main/java/com/baeldung/autovalue/AutoValueMoney.java similarity index 100% rename from autovalue-tutorial/src/main/java/com/baeldung/autovalue/AutoValueMoney.java rename to autovalue/src/main/java/com/baeldung/autovalue/AutoValueMoney.java diff --git a/autovalue-tutorial/src/main/java/com/baeldung/autovalue/AutoValueMoneyWithBuilder.java b/autovalue/src/main/java/com/baeldung/autovalue/AutoValueMoneyWithBuilder.java similarity index 100% rename from autovalue-tutorial/src/main/java/com/baeldung/autovalue/AutoValueMoneyWithBuilder.java rename to autovalue/src/main/java/com/baeldung/autovalue/AutoValueMoneyWithBuilder.java diff --git a/autovalue-tutorial/src/main/java/com/baeldung/autovalue/Foo.java b/autovalue/src/main/java/com/baeldung/autovalue/Foo.java similarity index 100% rename from autovalue-tutorial/src/main/java/com/baeldung/autovalue/Foo.java rename to autovalue/src/main/java/com/baeldung/autovalue/Foo.java diff --git a/autovalue-tutorial/src/main/java/com/baeldung/autovalue/ImmutableMoney.java b/autovalue/src/main/java/com/baeldung/autovalue/ImmutableMoney.java similarity index 100% rename from autovalue-tutorial/src/main/java/com/baeldung/autovalue/ImmutableMoney.java rename to autovalue/src/main/java/com/baeldung/autovalue/ImmutableMoney.java diff --git a/autovalue-tutorial/src/main/java/com/baeldung/autovalue/MutableMoney.java b/autovalue/src/main/java/com/baeldung/autovalue/MutableMoney.java similarity index 100% rename from autovalue-tutorial/src/main/java/com/baeldung/autovalue/MutableMoney.java rename to autovalue/src/main/java/com/baeldung/autovalue/MutableMoney.java diff --git a/autovalue-tutorial/src/test/java/com/baeldung/autovalue/MoneyTest.java b/autovalue/src/test/java/com/baeldung/autovalue/MoneyTest.java similarity index 100% rename from autovalue-tutorial/src/test/java/com/baeldung/autovalue/MoneyTest.java rename to autovalue/src/test/java/com/baeldung/autovalue/MoneyTest.java diff --git a/cdi/README.md b/cdi/README.md new file mode 100644 index 0000000000..a27c35772a --- /dev/null +++ b/cdi/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [CDI Interceptor vs Spring AspectJ](http://www.baeldung.com/cdi-interceptor-vs-spring-aspectj) diff --git a/cdi/pom.xml b/cdi/pom.xml new file mode 100644 index 0000000000..30dd167fa8 --- /dev/null +++ b/cdi/pom.xml @@ -0,0 +1,104 @@ + + + 4.0.0 + + com.baeldung + cdi + 1.0-SNAPSHOT + + + + org.springframework + spring-core + ${spring.version} + + + org.springframework + spring-context + ${spring.version} + + + + org.aspectj + aspectjweaver + 1.8.9 + + + org.jboss.weld.se + weld-se-core + 2.3.5.Final + + + + junit + junit + 4.12 + test + + + org.springframework + spring-test + ${spring.version} + test + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + 4.3.1.RELEASE + 2.19.1 + + + \ No newline at end of file diff --git a/cdi/src/main/java/com/baeldung/interceptor/Audited.java b/cdi/src/main/java/com/baeldung/interceptor/Audited.java new file mode 100644 index 0000000000..3df4bef95e --- /dev/null +++ b/cdi/src/main/java/com/baeldung/interceptor/Audited.java @@ -0,0 +1,14 @@ +package com.baeldung.interceptor; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.interceptor.InterceptorBinding; + +@InterceptorBinding +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +public @interface Audited { +} diff --git a/cdi/src/main/java/com/baeldung/interceptor/AuditedInterceptor.java b/cdi/src/main/java/com/baeldung/interceptor/AuditedInterceptor.java new file mode 100644 index 0000000000..c62d9a4127 --- /dev/null +++ b/cdi/src/main/java/com/baeldung/interceptor/AuditedInterceptor.java @@ -0,0 +1,20 @@ +package com.baeldung.interceptor; + +import javax.interceptor.AroundInvoke; +import javax.interceptor.Interceptor; +import javax.interceptor.InvocationContext; + +@Audited +@Interceptor +public class AuditedInterceptor { + public static boolean calledBefore = false; + public static boolean calledAfter = false; + + @AroundInvoke + public Object auditMethod(InvocationContext ctx) throws Exception { + calledBefore = true; + Object result = ctx.proceed(); + calledAfter = true; + return result; + } +} diff --git a/cdi/src/main/java/com/baeldung/service/SuperService.java b/cdi/src/main/java/com/baeldung/service/SuperService.java new file mode 100644 index 0000000000..e15f049342 --- /dev/null +++ b/cdi/src/main/java/com/baeldung/service/SuperService.java @@ -0,0 +1,10 @@ +package com.baeldung.service; + +import com.baeldung.interceptor.Audited; + +public class SuperService { + @Audited + public String deliverService(String uid) { + return uid; + } +} diff --git a/cdi/src/main/java/com/baeldung/spring/aspect/SpringTestAspect.java b/cdi/src/main/java/com/baeldung/spring/aspect/SpringTestAspect.java new file mode 100644 index 0000000000..e48039706d --- /dev/null +++ b/cdi/src/main/java/com/baeldung/spring/aspect/SpringTestAspect.java @@ -0,0 +1,23 @@ +package com.baeldung.spring.aspect; + +import java.util.List; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.beans.factory.annotation.Autowired; + +@Aspect +public class SpringTestAspect { + @Autowired + private List accumulator; + + @Around("execution(* com.baeldung.spring.service.SpringSuperService.*(..))") + public Object auditMethod(ProceedingJoinPoint jp) throws Throwable { + String methodName = jp.getSignature().getName(); + accumulator.add("Call to " + methodName); + Object obj = jp.proceed(); + accumulator.add("Method called successfully: " + methodName); + return obj; + } +} diff --git a/cdi/src/main/java/com/baeldung/spring/configuration/AppConfig.java b/cdi/src/main/java/com/baeldung/spring/configuration/AppConfig.java new file mode 100644 index 0000000000..b30c4a1326 --- /dev/null +++ b/cdi/src/main/java/com/baeldung/spring/configuration/AppConfig.java @@ -0,0 +1,30 @@ +package com.baeldung.spring.configuration; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +import com.baeldung.spring.aspect.SpringTestAspect; +import com.baeldung.spring.service.SpringSuperService; + +@Configuration +@EnableAspectJAutoProxy +public class AppConfig { + @Bean + public SpringSuperService springSuperService() { + return new SpringSuperService(); + } + + @Bean + public SpringTestAspect springTestAspect() { + return new SpringTestAspect(); + } + + @Bean + public List getAccumulator() { + return new ArrayList(); + } +} diff --git a/cdi/src/main/java/com/baeldung/spring/service/SpringSuperService.java b/cdi/src/main/java/com/baeldung/spring/service/SpringSuperService.java new file mode 100644 index 0000000000..082eb2e0f8 --- /dev/null +++ b/cdi/src/main/java/com/baeldung/spring/service/SpringSuperService.java @@ -0,0 +1,7 @@ +package com.baeldung.spring.service; + +public class SpringSuperService { + public String getInfoFromService(String code) { + return code; + } +} diff --git a/cdi/src/main/resources/META-INF/beans.xml b/cdi/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..d41b35e7d9 --- /dev/null +++ b/cdi/src/main/resources/META-INF/beans.xml @@ -0,0 +1,8 @@ + + + com.baeldung.interceptor.AuditedInterceptor + + \ No newline at end of file diff --git a/cdi/src/test/java/com/baeldung/test/InterceptorIntegrationTest.java b/cdi/src/test/java/com/baeldung/test/InterceptorIntegrationTest.java new file mode 100644 index 0000000000..cca8cb7495 --- /dev/null +++ b/cdi/src/test/java/com/baeldung/test/InterceptorIntegrationTest.java @@ -0,0 +1,38 @@ +package com.baeldung.test; + +import org.jboss.weld.environment.se.Weld; +import org.jboss.weld.environment.se.WeldContainer; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.interceptor.AuditedInterceptor; +import com.baeldung.service.SuperService; + +public class InterceptorIntegrationTest { + Weld weld; + WeldContainer container; + + @Before + public void init() { + weld = new Weld(); + container = weld.initialize(); + } + + @After + public void shutdown() { + weld.shutdown(); + } + + @Test + public void givenTheService_whenMethodAndInterceptorExecuted_thenOK() { + SuperService superService = container.select(SuperService.class).get(); + String code = "123456"; + superService.deliverService(code); + + Assert.assertTrue(AuditedInterceptor.calledBefore); + Assert.assertTrue(AuditedInterceptor.calledAfter); + } + +} diff --git a/cdi/src/test/java/com/baeldung/test/SpringInterceptorIntegrationTest.java b/cdi/src/test/java/com/baeldung/test/SpringInterceptorIntegrationTest.java new file mode 100644 index 0000000000..f711b0c8ce --- /dev/null +++ b/cdi/src/test/java/com/baeldung/test/SpringInterceptorIntegrationTest.java @@ -0,0 +1,38 @@ +package com.baeldung.test; + +import static org.hamcrest.CoreMatchers.is; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.configuration.AppConfig; +import com.baeldung.spring.service.SpringSuperService; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = { AppConfig.class }) +public class SpringInterceptorIntegrationTest { + @Autowired + SpringSuperService springSuperService; + + @Autowired + private List accumulator; + + // + + @Test + public void givenService_whenServiceAndAspectExecuted_thenOk() { + String code = "123456"; + String result = springSuperService.getInfoFromService(code); + + Assert.assertThat(accumulator.size(), is(2)); + Assert.assertThat(accumulator.get(0), is("Call to getInfoFromService")); + Assert.assertThat(accumulator.get(1), is("Method called successfully: getInfoFromService")); + } + +} diff --git a/core-java-8/README.md b/core-java-8/README.md deleted file mode 100644 index e6bac2a4c9..0000000000 --- a/core-java-8/README.md +++ /dev/null @@ -1,14 +0,0 @@ -========= - -## Core Java 8 Cookbooks and Examples - -### Relevant Articles: -- [Java 8 – Powerful Comparison with Lambdas](http://www.baeldung.com/java-8-sort-lambda) -- [Java – Directory Size](http://www.baeldung.com/java-folder-size) -- [Java – Try with Resources](http://www.baeldung.com/java-try-with-resources) -- [A Guide to the Java ExecutorService](http://www.baeldung.com/java-executor-service-tutorial) -- [Java 8 New Features](http://www.baeldung.com/java-8-new-features) -- [Lambda Expressions and Functional Interfaces: Tips and Best Practices](http://www.baeldung.com/java-8-lambda-expressions-tips) -- [The Double Colon Operator in Java 8](http://www.baeldung.com/java-8-double-colon-operator) -- [Java 8 Streams Advanced](http://www.baeldung.com/java-8-streams) -- [Java 8 Collectors](http://www.baeldung.com/java-8-collectors) \ No newline at end of file diff --git a/core-java-8/pom.xml b/core-java-8/pom.xml deleted file mode 100644 index 63df0e1b95..0000000000 --- a/core-java-8/pom.xml +++ /dev/null @@ -1,138 +0,0 @@ - - 4.0.0 - com.baeldung - core-java8 - 0.1-SNAPSHOT - - core-java8 - - - - - - - commons-io - commons-io - 2.4 - - - - com.google.guava - guava - ${guava.version} - - - - org.apache.commons - commons-collections4 - 4.0 - - - - commons-codec - commons-codec - 1.10 - - - - org.apache.commons - commons-lang3 - 3.3.2 - - - - org.slf4j - slf4j-api - ${org.slf4j.version} - - - - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - - - - junit - junit - ${junit.version} - test - - - - org.assertj - assertj-core - 3.5.1 - test - - - - org.mockito - mockito-core - ${mockito.version} - test - - - - - - core-java-8 - - - src/main/resources - true - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - 1.8 - 1.8 - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - - - - - - - 1.7.13 - 1.0.13 - - - 5.1.3.Final - - - 19.0 - 3.4 - - - 1.3 - 4.12 - 1.10.19 - - - 3.5.1 - 2.6 - 2.19.1 - 2.7 - - - - \ No newline at end of file diff --git a/core-java-8/src/main/java/com/baeldung/enums/Pizza.java b/core-java-8/src/main/java/com/baeldung/enums/Pizza.java deleted file mode 100644 index 5bc2d9a9eb..0000000000 --- a/core-java-8/src/main/java/com/baeldung/enums/Pizza.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.baeldung.enums; - -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.List; -import java.util.stream.Collectors; - -public class Pizza { - - private static EnumSet deliveredPizzaStatuses = - EnumSet.of(PizzaStatusEnum.DELIVERED); - - private PizzaStatusEnum status; - - public enum PizzaStatusEnum { - ORDERED(5) { - @Override - public boolean isOrdered() { - return true; - } - }, - READY(2) { - @Override - public boolean isReady() { - return true; - } - }, - DELIVERED(0) { - @Override - public boolean isDelivered() { - return true; - } - }; - - private int timeToDelivery; - - public boolean isOrdered() { - return false; - } - - public boolean isReady() { - return false; - } - - public boolean isDelivered() { - return false; - } - - public int getTimeToDelivery() { - return timeToDelivery; - } - - PizzaStatusEnum(int timeToDelivery) { - this.timeToDelivery = timeToDelivery; - } - } - - public PizzaStatusEnum getStatus() { - return status; - } - - public void setStatus(PizzaStatusEnum status) { - this.status = status; - } - - public boolean isDeliverable() { - return this.status.isReady(); - } - - public void printTimeToDeliver() { - System.out.println("Time to delivery is " + this.getStatus().getTimeToDelivery() + " days"); - } - - public static List getAllUndeliveredPizzas(List input) { - return input.stream().filter((s) -> !deliveredPizzaStatuses.contains(s.getStatus())).collect(Collectors.toList()); - } - - public static EnumMap> groupPizzaByStatus(List pzList) { - return pzList.stream().collect( - Collectors.groupingBy(Pizza::getStatus, - () -> new EnumMap<>(PizzaStatusEnum.class), Collectors.toList())); - } - - public void deliver() { - if (isDeliverable()) { - PizzaDeliverySystemConfiguration.getInstance().getDeliveryStrategy().deliver(this); - this.setStatus(PizzaStatusEnum.DELIVERED); - } - } - -} \ No newline at end of file diff --git a/core-java-8/src/main/java/com/baeldung/enums/PizzaDeliveryStrategy.java b/core-java-8/src/main/java/com/baeldung/enums/PizzaDeliveryStrategy.java deleted file mode 100644 index ed65919387..0000000000 --- a/core-java-8/src/main/java/com/baeldung/enums/PizzaDeliveryStrategy.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.baeldung.enums; - -public enum PizzaDeliveryStrategy { - EXPRESS { - @Override - public void deliver(Pizza pz) { - System.out.println("Pizza will be delivered in express mode"); - } - }, - NORMAL { - @Override - public void deliver(Pizza pz) { - System.out.println("Pizza will be delivered in normal mode"); - } - }; - - public abstract void deliver(Pizza pz); -} diff --git a/core-java-8/src/main/java/com/baeldung/enums/PizzaDeliverySystemConfiguration.java b/core-java-8/src/main/java/com/baeldung/enums/PizzaDeliverySystemConfiguration.java deleted file mode 100644 index 5ccff5e959..0000000000 --- a/core-java-8/src/main/java/com/baeldung/enums/PizzaDeliverySystemConfiguration.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.baeldung.enums; - - -public enum PizzaDeliverySystemConfiguration { - INSTANCE; - - PizzaDeliverySystemConfiguration() { - // Do the configuration initialization which - // involves overriding defaults like delivery strategy - } - - private PizzaDeliveryStrategy deliveryStrategy = PizzaDeliveryStrategy.NORMAL; - - public static PizzaDeliverySystemConfiguration getInstance() { - return INSTANCE; - } - - public PizzaDeliveryStrategy getDeliveryStrategy() { - return deliveryStrategy; - } - -} diff --git a/core-java-8/src/main/resources/compressed.zip b/core-java-8/src/main/resources/compressed.zip deleted file mode 100644 index 03f840ae2b..0000000000 Binary files a/core-java-8/src/main/resources/compressed.zip and /dev/null differ diff --git a/core-java-8/src/main/resources/unzipTest/test1.txt b/core-java-8/src/main/resources/unzipTest/test1.txt deleted file mode 100644 index c57eff55eb..0000000000 --- a/core-java-8/src/main/resources/unzipTest/test1.txt +++ /dev/null @@ -1 +0,0 @@ -Hello World! \ No newline at end of file diff --git a/core-java-8/src/main/resources/zipTest/test1.txt b/core-java-8/src/main/resources/zipTest/test1.txt deleted file mode 100644 index c57eff55eb..0000000000 --- a/core-java-8/src/main/resources/zipTest/test1.txt +++ /dev/null @@ -1 +0,0 @@ -Hello World! \ No newline at end of file diff --git a/core-java-8/src/main/resources/zipTest/test2.txt b/core-java-8/src/main/resources/zipTest/test2.txt deleted file mode 100644 index f0fb0f14d1..0000000000 --- a/core-java-8/src/main/resources/zipTest/test2.txt +++ /dev/null @@ -1 +0,0 @@ -My Name is John \ No newline at end of file diff --git a/core-java-8/src/main/resources/zipTest/testFolder/test3.txt b/core-java-8/src/main/resources/zipTest/testFolder/test3.txt deleted file mode 100644 index 882edb168e..0000000000 --- a/core-java-8/src/main/resources/zipTest/testFolder/test3.txt +++ /dev/null @@ -1 +0,0 @@ -My Name is Tom \ No newline at end of file diff --git a/core-java-8/src/main/resources/zipTest/testFolder/test4.txt b/core-java-8/src/main/resources/zipTest/testFolder/test4.txt deleted file mode 100644 index a78c3fadc8..0000000000 --- a/core-java-8/src/main/resources/zipTest/testFolder/test4.txt +++ /dev/null @@ -1 +0,0 @@ -My Name is Jane \ No newline at end of file diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTest.java b/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTest.java deleted file mode 100644 index 8af33393be..0000000000 --- a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.baeldung.datetime; - -import java.time.DayOfWeek; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.Month; - -import org.junit.Assert; -import org.junit.Test; - -public class UseLocalDateTest { - - UseLocalDate useLocalDate = new UseLocalDate(); - - @Test - public void givenValues_whenUsingFactoryOf_thenLocalDate(){ - Assert.assertEquals("2016-05-10",useLocalDate.getLocalDateUsingFactoryOfMethod(2016,5,10).toString()); - } - - @Test - public void givenString_whenUsingParse_thenLocalDate(){ - Assert.assertEquals("2016-05-10",useLocalDate.getLocalDateUsingParseMethod("2016-05-10").toString()); - } - - @Test - public void whenUsingClock_thenLocalDate(){ - Assert.assertEquals(LocalDate.now(),useLocalDate.getLocalDateFromClock()); - } - - @Test - public void givenDate_whenUsingPlus_thenNextDay(){ - Assert.assertEquals(LocalDate.now().plusDays(1),useLocalDate.getNextDay(LocalDate.now())); - } - - @Test - public void givenDate_whenUsingMinus_thenPreviousDay(){ - Assert.assertEquals(LocalDate.now().minusDays(1),useLocalDate.getPreviousDay(LocalDate.now())); - } - - @Test - public void givenToday_whenUsingGetDayOfWeek_thenDayOfWeek(){ - Assert.assertEquals(DayOfWeek.SUNDAY,useLocalDate.getDayOfWeek(LocalDate.parse("2016-05-22"))); - } - - @Test - public void givenToday_whenUsingWithTemporalAdjuster_thenFirstDayOfMonth(){ - Assert.assertEquals(1,useLocalDate.getFirstDayOfMonth().getDayOfMonth()); - } - - @Test - public void givenLocalDate_whenUsingAtStartOfDay_thenReturnMidnight(){ - Assert.assertEquals(LocalDateTime.parse("2016-05-22T00:00:00"),useLocalDate.getStartOfDay(LocalDate.parse("2016-05-22"))); - } - -} diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTimeTest.java b/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTimeTest.java deleted file mode 100644 index 69a289fd02..0000000000 --- a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTimeTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.baeldung.datetime; - -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.Month; - -import org.junit.Assert; -import org.junit.Test; - -public class UseLocalDateTimeTest { - - UseLocalDateTime useLocalDateTime = new UseLocalDateTime(); - - @Test - public void givenString_whenUsingParse_thenLocalDateTime(){ - Assert.assertEquals(LocalDate.of(2016, Month.MAY, 10),useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30").toLocalDate()); - Assert.assertEquals(LocalTime.of(6,30),useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30").toLocalTime()); - } -} diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalTimeTest.java b/core-java-8/src/test/java/com/baeldung/datetime/UseLocalTimeTest.java deleted file mode 100644 index 7776fad363..0000000000 --- a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalTimeTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.baeldung.datetime; - -import java.time.LocalTime; - -import org.junit.Assert; -import org.junit.Test; - -public class UseLocalTimeTest { - - UseLocalTime useLocalTime = new UseLocalTime(); - - @Test - public void givenValues_whenUsingFactoryOf_thenLocalTime(){ - Assert.assertEquals("07:07:07",useLocalTime.getLocalTimeUsingFactoryOfMethod(7,7,7).toString()); - } - - @Test - public void givenString_whenUsingParse_thenLocalTime(){ - Assert.assertEquals("06:30",useLocalTime.getLocalTimeUsingParseMethod("06:30").toString()); - } - - @Test - public void givenTime_whenAddHour_thenLocalTime(){ - Assert.assertEquals("07:30",useLocalTime.addAnHour(LocalTime.of(6,30)).toString()); - } - - @Test - public void getHourFromLocalTime(){ - Assert.assertEquals(1, useLocalTime.getHourFromLocalTime(LocalTime.of(1,1))); - } - - @Test - public void getLocalTimeWithMinuteSetToValue(){ - Assert.assertEquals(LocalTime.of(10, 20), useLocalTime.getLocalTimeWithMinuteSetToValue(LocalTime.of(10,10), 20)); - } -} diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseZonedDateTimeTest.java b/core-java-8/src/test/java/com/baeldung/datetime/UseZonedDateTimeTest.java deleted file mode 100644 index 5af01ad678..0000000000 --- a/core-java-8/src/test/java/com/baeldung/datetime/UseZonedDateTimeTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.baeldung.datetime; - -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.ZonedDateTime; - -import org.junit.Assert; -import org.junit.Test; - -public class UseZonedDateTimeTest { - - UseZonedDateTime zonedDateTime=new UseZonedDateTime(); - - @Test - public void givenZoneId_thenZonedDateTime(){ - ZoneId zoneId=ZoneId.of("Europe/Paris"); - ZonedDateTime zonedDatetime=zonedDateTime.getZonedDateTime(LocalDateTime.parse("2016-05-20T06:30"), zoneId); - Assert.assertEquals(zoneId,ZoneId.from(zonedDatetime)); - } -} diff --git a/core-java-8/.gitignore b/core-java-9/.gitignore similarity index 100% rename from core-java-8/.gitignore rename to core-java-9/.gitignore diff --git a/core-java-9/README.md b/core-java-9/README.md new file mode 100644 index 0000000000..fbe5f908aa --- /dev/null +++ b/core-java-9/README.md @@ -0,0 +1,5 @@ +========= + +## Core Java 9 Examples + +[Java 9 New Features](http://www.baeldung.com/new-java-9) diff --git a/core-java-9/pom.xml b/core-java-9/pom.xml new file mode 100644 index 0000000000..844ad6a782 --- /dev/null +++ b/core-java-9/pom.xml @@ -0,0 +1,93 @@ + + 4.0.0 + com.baeldung + core-java9 + 0.2-SNAPSHOT + + core-java9 + + + + apache.snapshots + http://repository.apache.org/snapshots/ + + + + + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + + + + org.hamcrest + hamcrest-library + ${org.hamcrest.version} + test + + + + junit + junit + ${junit.version} + test + + + + org.mockito + mockito-core + ${mockito.version} + test + + + + + + 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} + + + + + + + + + 1.7.13 + 1.0.13 + + + + 3.6-jigsaw-SNAPSHOT + 2.19.1 + + + 1.3 + 4.12 + 1.10.19 + + + diff --git a/core-java-8/src/main/java/.gitignore b/core-java-9/src/main/java/.gitignore similarity index 100% rename from core-java-8/src/main/java/.gitignore rename to core-java-9/src/main/java/.gitignore diff --git a/core-java-9/src/main/java/com/baeldung/java9/language/PrivateInterface.java b/core-java-9/src/main/java/com/baeldung/java9/language/PrivateInterface.java new file mode 100644 index 0000000000..fd6a496b18 --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/language/PrivateInterface.java @@ -0,0 +1,23 @@ +package com.baeldung.java9.language; + +public interface PrivateInterface { + + private static String staticPrivate() { + return "static private"; + } + + private String instancePrivate() { + return "instance private"; + } + + public default void check(){ + String result = staticPrivate(); + if (!result.equals("static private")) + throw new AssertionError("Incorrect result for static private interface method"); + PrivateInterface pvt = new PrivateInterface() { + }; + result = pvt.instancePrivate(); + if (!result.equals("instance private")) + throw new AssertionError("Incorrect result for instance private interface method"); + } +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/process/ProcessUtils.java b/core-java-9/src/main/java/com/baeldung/java9/process/ProcessUtils.java new file mode 100644 index 0000000000..d6682bd0c8 --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/process/ProcessUtils.java @@ -0,0 +1,44 @@ +package com.baeldung.java9.process; + +import java.io.File; +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.time.Duration; +import java.time.Instant; +import java.util.stream.Stream; + + +public class ProcessUtils { + + public static String getClassPath(){ + String cp = System.getProperty("java.class.path"); + System.out.println("ClassPath is "+cp); + return cp; + } + + public static File getJavaCmd() throws IOException{ + String javaHome = System.getProperty("java.home"); + File javaCmd; + if(System.getProperty("os.name").startsWith("Win")){ + javaCmd = new File(javaHome, "bin/java.exe"); + }else{ + javaCmd = new File(javaHome, "bin/java"); + } + if(javaCmd.canExecute()){ + return javaCmd; + }else{ + throw new UnsupportedOperationException(javaCmd.getCanonicalPath() + " is not executable"); + } + } + + public static String getMainClass(){ + return System.getProperty("sun.java.command"); + } + + public static String getSystemProperties(){ + StringBuilder sb = new StringBuilder(); + System.getProperties().forEach((s1, s2) -> sb.append(s1 +" - "+ s2) ); + return sb.toString(); + } +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/process/ServiceMain.java b/core-java-9/src/main/java/com/baeldung/java9/process/ServiceMain.java new file mode 100644 index 0000000000..458f746496 --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/process/ServiceMain.java @@ -0,0 +1,22 @@ +package com.baeldung.java9.process; + +import java.util.Optional; + +public class ServiceMain { + + public static void main(String[] args) throws InterruptedException { + ProcessHandle thisProcess = ProcessHandle.current(); + long pid = thisProcess.getPid(); + + + Optional opArgs = Optional.ofNullable(args); + String procName = opArgs.map(str -> str.length > 0 ? str[0] : null).orElse(System.getProperty("sun.java.command")); + + for (int i = 0; i < 10000; i++) { + System.out.println("Process " + procName + " with ID " + pid + " is running!"); + Thread.sleep(10000); + } + + } + +} diff --git a/core-java-8/src/main/resources/logback.xml b/core-java-9/src/main/resources/logback.xml similarity index 100% rename from core-java-8/src/main/resources/logback.xml rename to core-java-9/src/main/resources/logback.xml diff --git a/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalsStreamTest.java b/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalsStreamTest.java new file mode 100644 index 0000000000..b0684a94f8 --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalsStreamTest.java @@ -0,0 +1,71 @@ +package com.baeldung.java8; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.Before; +import org.junit.Test; + +public class Java9OptionalsStreamTest { + + private static List> listOfOptionals = Arrays.asList(Optional.empty(), Optional.of("foo"), Optional.empty(), Optional.of("bar")); + + @Test + public void filterOutPresentOptionalsWithFilter() { + assertEquals(4, listOfOptionals.size()); + + List filteredList = listOfOptionals.stream() + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + + assertEquals(2, filteredList.size()); + assertEquals("foo", filteredList.get(0)); + assertEquals("bar", filteredList.get(1)); + } + + @Test + public void filterOutPresentOptionalsWithFlatMap() { + assertEquals(4, listOfOptionals.size()); + + List filteredList = listOfOptionals.stream() + .flatMap(o -> o.isPresent() ? Stream.of(o.get()) : Stream.empty()) + .collect(Collectors.toList()); + assertEquals(2, filteredList.size()); + + assertEquals("foo", filteredList.get(0)); + assertEquals("bar", filteredList.get(1)); + } + + @Test + public void filterOutPresentOptionalsWithFlatMap2() { + assertEquals(4, listOfOptionals.size()); + + List filteredList = listOfOptionals.stream() + .flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty)) + .collect(Collectors.toList()); + assertEquals(2, filteredList.size()); + + assertEquals("foo", filteredList.get(0)); + assertEquals("bar", filteredList.get(1)); + } + + @Test + public void filterOutPresentOptionalsWithJava9() { + assertEquals(4, listOfOptionals.size()); + + List filteredList = listOfOptionals.stream() + .flatMap(Optional::stream) + .collect(Collectors.toList()); + + assertEquals(2, filteredList.size()); + assertEquals("foo", filteredList.get(0)); + assertEquals("bar", filteredList.get(1)); + } + +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/MultiResultionImageTest.java b/core-java-9/src/test/java/com/baeldung/java9/MultiResultionImageTest.java new file mode 100644 index 0000000000..a00646e4db --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/MultiResultionImageTest.java @@ -0,0 +1,47 @@ +package com.baeldung.java9; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +import java.awt.Image; +import java.awt.image.BaseMultiResolutionImage; +import java.awt.image.BufferedImage; +import java.awt.image.MultiResolutionImage; +import java.util.List; + +import org.junit.Test; + +public class MultiResultionImageTest { + + + @Test + public void baseMultiResImageTest() { + int baseIndex = 1; + int length = 4; + BufferedImage[] resolutionVariants = new BufferedImage[length]; + for (int i = 0; i < length; i++) { + resolutionVariants[i] = createImage(i); + } + MultiResolutionImage bmrImage = new BaseMultiResolutionImage(baseIndex, resolutionVariants); + List rvImageList = bmrImage.getResolutionVariants(); + assertEquals("MultiResoltion Image shoudl contain the same number of resolution variants!", rvImageList.size(), length); + + for (int i = 0; i < length; i++) { + int imageSize = getSize(i); + Image testRVImage = bmrImage.getResolutionVariant(imageSize, imageSize); + assertSame("Images should be the same", testRVImage, resolutionVariants[i]); + } + + } + + private static int getSize(int i) { + return 8 * (i + 1); + } + + + private static BufferedImage createImage(int i) { + return new BufferedImage(getSize(i), getSize(i), + BufferedImage.TYPE_INT_RGB); + } + +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/OptionalToStreamTest.java b/core-java-9/src/test/java/com/baeldung/java9/OptionalToStreamTest.java new file mode 100644 index 0000000000..56b4bb7b8c --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/OptionalToStreamTest.java @@ -0,0 +1,21 @@ +package com.baeldung.java9; + +import java.util.Optional; +import java.util.stream.Stream; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; + +public class OptionalToStreamTest { + + @Test + public void testOptionalToStream() { + Optional op = Optional.ofNullable("String value"); + Stream strOptionalStream = op.stream(); + Stream filteredStream = strOptionalStream.filter((str) -> { + return str != null && str.startsWith("String"); + }); + assertEquals(1, filteredStream.count()); + + } +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/README.MD b/core-java-9/src/test/java/com/baeldung/java9/README.MD new file mode 100644 index 0000000000..2f44a2336b --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/README.MD @@ -0,0 +1,2 @@ +### Relevant Artiles: +- [Filtering a Stream of Optionals in Java](http://www.baeldung.com/java-filter-stream-of-optional) diff --git a/core-java-9/src/test/java/com/baeldung/java9/SetExamplesTest.java b/core-java-9/src/test/java/com/baeldung/java9/SetExamplesTest.java new file mode 100644 index 0000000000..0f8db83d9c --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/SetExamplesTest.java @@ -0,0 +1,26 @@ +package com.baeldung.java9; + +import java.util.Set; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class SetExamplesTest { + + @Test + public void testUnmutableSet() { + Set strKeySet = Set.of("key1", "key2", "key3"); + try { + strKeySet.add("newKey"); + } catch (UnsupportedOperationException uoe) { + } + assertEquals(strKeySet.size(), 3); + } + + @Test + public void testArrayToSet() { + Integer[] intArray = new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; + Set intSet = Set.of(intArray); + assertEquals(intSet.size(), intArray.length); + } +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsTest.java b/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsTest.java new file mode 100644 index 0000000000..ab28b0a805 --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsTest.java @@ -0,0 +1,126 @@ +package com.baeldung.java9.httpclient; + + + +import static java.net.HttpURLConnection.HTTP_OK; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.net.CookieManager; +import java.net.CookiePolicy; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpHeaders; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.security.NoSuchAlgorithmException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; + +import org.junit.Before; +import org.junit.Test; + +public class SimpleHttpRequestsTest { + + private URI httpURI; + + @Before + public void init() throws URISyntaxException { + httpURI = new URI("http://www.baeldung.com/"); + } + + @Test + public void quickGet() throws IOException, InterruptedException, URISyntaxException { + HttpRequest request = HttpRequest.create( httpURI ).GET(); + HttpResponse response = request.response(); + int responseStatusCode = response.statusCode(); + String responseBody = response.body(HttpResponse.asString()); + assertTrue("Get response status code is bigger then 400", responseStatusCode < 400); + } + + @Test + public void asynchronousGet() throws URISyntaxException, IOException, InterruptedException, ExecutionException{ + HttpRequest request = HttpRequest.create(httpURI).GET(); + long before = System.currentTimeMillis(); + CompletableFuture futureResponse = request.responseAsync(); + futureResponse.thenAccept( response -> { + String responseBody = response.body(HttpResponse.asString()); + }); + HttpResponse resp = futureResponse.get(); + HttpHeaders hs = resp.headers(); + assertTrue("There should be more then 1 header.", hs.map().size() >1); + } + + @Test + public void postMehtod() throws URISyntaxException, IOException, InterruptedException { + HttpRequest.Builder requestBuilder = HttpRequest.create(httpURI); + requestBuilder.body(HttpRequest.fromString("param1=foo,param2=bar")).followRedirects(HttpClient.Redirect.SECURE); + HttpRequest request = requestBuilder.POST(); + HttpResponse response = request.response(); + int statusCode = response.statusCode(); + assertTrue("HTTP return code", statusCode == HTTP_OK); + } + + @Test + public void configureHttpClient() throws NoSuchAlgorithmException, URISyntaxException, IOException, InterruptedException{ + CookieManager cManager = new CookieManager(); + cManager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER); + + SSLParameters sslParam = new SSLParameters (new String[] { "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" }, new String[] { "TLSv1.2" }); + + HttpClient.Builder hcBuilder = HttpClient.create(); + hcBuilder.cookieManager(cManager).sslContext(SSLContext.getDefault()).sslParameters(sslParam); + HttpClient httpClient = hcBuilder.build(); + HttpRequest.Builder reqBuilder = httpClient.request(new URI("https://www.facebook.com")); + + HttpRequest request = reqBuilder.followRedirects(HttpClient.Redirect.ALWAYS).GET(); + HttpResponse response = request.response(); + int statusCode = response.statusCode(); + assertTrue("HTTP return code", statusCode == HTTP_OK); + } + + SSLParameters getDefaultSSLParameters() throws NoSuchAlgorithmException{ + SSLParameters sslP1 = SSLContext.getDefault().getSupportedSSLParameters(); + String [] proto = sslP1.getApplicationProtocols(); + String [] cifers = sslP1.getCipherSuites(); + System.out.println(printStringArr(proto)); + System.out.println(printStringArr(cifers)); + return sslP1; + } + + String printStringArr(String ... args ){ + if(args == null){ + return null; + } + StringBuilder sb = new StringBuilder(); + for (String s : args){ + sb.append(s); + sb.append("\n"); + } + return sb.toString(); + } + + String printHeaders(HttpHeaders h){ + if(h == null){ + return null; + } + + StringBuilder sb = new StringBuilder(); + Map> hMap = h.map(); + for(String k : hMap.keySet()){ + sb.append(k).append(":"); + List l = hMap.get(k); + if( l != null ){ + l.forEach( s -> { sb.append(s).append(","); } ); + } + sb.append("\n"); + } + return sb.toString(); + } +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/language/DiamondTest.java b/core-java-9/src/test/java/com/baeldung/java9/language/DiamondTest.java new file mode 100644 index 0000000000..33da6486f4 --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/language/DiamondTest.java @@ -0,0 +1,36 @@ +package com.baeldung.java9.language; + +import org.junit.Test; + +public class DiamondTest { + + static class FooClass { + FooClass(X x) { + } + + FooClass(X x, Z z) { + } + } + + @Test + public void diamondTest() { + FooClass fc = new FooClass<>(1) { + }; + FooClass fc0 = new FooClass<>(1) { + }; + FooClass fc1 = new FooClass<>(1) { + }; + FooClass fc2 = new FooClass<>(1) { + }; + + FooClass fc3 = new FooClass<>(1, "") { + }; + FooClass fc4 = new FooClass<>(1, "") { + }; + FooClass fc5 = new FooClass<>(1, "") { + }; + FooClass fc6 = new FooClass<>(1, "") { + }; + + } +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/language/PrivateInterfaceTest.java b/core-java-9/src/test/java/com/baeldung/java9/language/PrivateInterfaceTest.java new file mode 100644 index 0000000000..29ef3930f8 --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/language/PrivateInterfaceTest.java @@ -0,0 +1,15 @@ +package com.baeldung.java9.language; + +import com.baeldung.java9.language.PrivateInterface; +import org.junit.Test; + +public class PrivateInterfaceTest { + + @Test + public void test() { + PrivateInterface piClass = new PrivateInterface() { + }; + piClass.check(); + } + +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/language/TryWithResourcesTest.java b/core-java-9/src/test/java/com/baeldung/java9/language/TryWithResourcesTest.java new file mode 100644 index 0000000000..687dfbc390 --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/language/TryWithResourcesTest.java @@ -0,0 +1,70 @@ +package com.baeldung.java9.language; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class TryWithResourcesTest { + + static int closeCount = 0; + + static class MyAutoCloseable implements AutoCloseable{ + final FinalWrapper finalWrapper = new FinalWrapper(); + + public void close() { + closeCount++; + } + + static class FinalWrapper { + public final AutoCloseable finalCloseable = new AutoCloseable() { + @Override + public void close() throws Exception { + closeCount++; + } + }; + } + } + + @Test + public void tryWithResourcesTest() { + MyAutoCloseable mac = new MyAutoCloseable(); + + try (mac) { + assertEquals("Expected and Actual does not match", 0, closeCount); + } + + try (mac.finalWrapper.finalCloseable) { + assertEquals("Expected and Actual does not match", 1, closeCount); + } catch (Exception ex) { + } + + try (new MyAutoCloseable() { }.finalWrapper.finalCloseable) { + assertEquals("Expected and Actual does not match", 2, closeCount); + } catch (Exception ex) { + } + + try ((closeCount > 0 ? mac : new MyAutoCloseable()).finalWrapper.finalCloseable) { + assertEquals("Expected and Actual does not match", 3, closeCount); + } catch (Exception ex) { + } + + try { + throw new CloseableException(); + } catch (CloseableException ex) { + try (ex) { + assertEquals("Expected and Actual does not match", 4, closeCount); + } + } + assertEquals("Expected and Actual does not match", 5, closeCount); + } + + + static class CloseableException extends Exception implements AutoCloseable { + @Override + public void close() { + closeCount++; + } + } + +} + + diff --git a/core-java-9/src/test/java/com/baeldung/java9/language/stream/StreamFeaturesTest.java b/core-java-9/src/test/java/com/baeldung/java9/language/stream/StreamFeaturesTest.java new file mode 100644 index 0000000000..a260e84164 --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/language/stream/StreamFeaturesTest.java @@ -0,0 +1,119 @@ +package com.baeldung.java9.language.stream; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.lang.Integer.*; +import static org.junit.Assert.assertEquals; + +public class StreamFeaturesTest { + + public static class TakeAndDropWhileTest { + + public Stream getStreamAfterTakeWhileOperation() { + return Stream + .iterate("", s -> s + "s") + .takeWhile(s -> s.length() < 10); + } + + public Stream getStreamAfterDropWhileOperation() { + return Stream + .iterate("", s -> s + "s") + .takeWhile(s -> s.length() < 10) + .dropWhile(s -> !s.contains("sssss")); + } + + @Test + public void testTakeWhileOperation() { + List list = getStreamAfterTakeWhileOperation().collect(Collectors.toList()); + + assertEquals(10, list.size()); + + assertEquals("", list.get(0)); + assertEquals("ss", list.get(2)); + assertEquals("sssssssss", list.get(list.size() - 1)); + } + + @Test + public void testDropWhileOperation() { + List list = getStreamAfterDropWhileOperation().collect(Collectors.toList()); + + assertEquals(5, list.size()); + + assertEquals("sssss", list.get(0)); + assertEquals("sssssss", list.get(2)); + assertEquals("sssssssss", list.get(list.size() - 1)); + } + + } + + public static class IterateTest { + + private Stream getStream() { + return Stream.iterate(0, i -> i < 10, i -> i + 1); + } + + @Test + public void testIterateOperation() { + List list = getStream().collect(Collectors.toList()); + + assertEquals(10, list.size()); + + assertEquals(valueOf(0), list.get(0)); + assertEquals(valueOf(5), list.get(5)); + assertEquals(valueOf(9), list.get(list.size() - 1)); + } + + } + + public static class OfNullableTest { + + private List collection = Arrays.asList("A", "B", "C"); + private Map map = new HashMap<>() {{ + put("A", 10); + put("C", 30); + }}; + + private Stream getStreamWithOfNullable() { + return collection.stream() + .flatMap(s -> Stream.ofNullable(map.get(s))); + } + + private Stream getStream() { + return collection.stream() + .flatMap(s -> { + Integer temp = map.get(s); + return temp != null ? Stream.of(temp) : Stream.empty(); + }); + } + + private List testOfNullableFrom(Stream stream) { + List list = stream.collect(Collectors.toList()); + + assertEquals(2, list.size()); + + assertEquals(valueOf(10), list.get(0)); + assertEquals(valueOf(30), list.get(list.size() - 1)); + + return list; + } + + @Test + public void testOfNullable() { + + assertEquals( + testOfNullableFrom(getStream()), + testOfNullableFrom(getStreamWithOfNullable()) + ); + + } + + } + +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/process/ProcessApi.java b/core-java-9/src/test/java/com/baeldung/java9/process/ProcessApi.java new file mode 100644 index 0000000000..419516cb64 --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/process/ProcessApi.java @@ -0,0 +1,112 @@ +package com.baeldung.java9.process; + +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Stream; + +import org.junit.Before; +import org.junit.Test; + +import junit.framework.Assert; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class ProcessApi { + + + @Before + public void init() { + + } + + @Test + public void processInfoExample()throws NoSuchAlgorithmException{ + ProcessHandle self = ProcessHandle.current(); + long PID = self.getPid(); + ProcessHandle.Info procInfo = self.info(); + Optional args = procInfo.arguments(); + Optional cmd = procInfo.commandLine(); + Optional startTime = procInfo.startInstant(); + Optional cpuUsage = procInfo.totalCpuDuration(); + + waistCPU(); + System.out.println("Args "+ args); + System.out.println("Command " +cmd.orElse("EmptyCmd")); + System.out.println("Start time: "+ startTime.get().toString()); + System.out.println(cpuUsage.get().toMillis()); + + Stream allProc = ProcessHandle.current().children(); + allProc.forEach(p -> { + System.out.println("Proc "+ p.getPid()); + }); + + } + + @Test + public void createAndDestroyProcess() throws IOException, InterruptedException{ + int numberOfChildProcesses = 5; + for(int i=0; i < numberOfChildProcesses; i++){ + createNewJVM(ServiceMain.class, i).getPid(); + } + + Stream childProc = ProcessHandle.current().children(); + assertEquals( childProc.count(), numberOfChildProcesses); + + childProc = ProcessHandle.current().children(); + childProc.forEach(processHandle -> { + assertTrue("Process "+ processHandle.getPid() +" should be alive!", processHandle.isAlive()); + CompletableFuture onProcExit = processHandle.onExit(); + onProcExit.thenAccept(procHandle -> { + System.out.println("Process with PID "+ procHandle.getPid() + " has stopped"); + }); + }); + + Thread.sleep(10000); + + childProc = ProcessHandle.current().children(); + childProc.forEach(procHandle -> { + assertTrue("Could not kill process "+procHandle.getPid(), procHandle.destroy()); + }); + + Thread.sleep(5000); + + childProc = ProcessHandle.current().children(); + childProc.forEach(procHandle -> { + assertFalse("Process "+ procHandle.getPid() +" should not be alive!", procHandle.isAlive()); + }); + + } + + private Process createNewJVM(Class mainClass, int number) throws IOException{ + ArrayList cmdParams = new ArrayList(5); + cmdParams.add(ProcessUtils.getJavaCmd().getAbsolutePath()); + cmdParams.add("-cp"); + cmdParams.add(ProcessUtils.getClassPath()); + cmdParams.add(mainClass.getName()); + cmdParams.add("Service "+ number); + ProcessBuilder myService = new ProcessBuilder(cmdParams); + myService.inheritIO(); + return myService.start(); + } + + private void waistCPU() throws NoSuchAlgorithmException{ + ArrayList randArr = new ArrayList(4096); + SecureRandom sr = SecureRandom.getInstanceStrong(); + Duration somecpu = Duration.ofMillis(4200L); + Instant end = Instant.now().plus(somecpu); + while (Instant.now().isBefore(end)) { + //System.out.println(sr.nextInt()); + randArr.add( sr.nextInt() ); + } + } + +} diff --git a/core-java-8/src/test/resources/.gitignore b/core-java-9/src/test/resources/.gitignore similarity index 100% rename from core-java-8/src/test/resources/.gitignore rename to core-java-9/src/test/resources/.gitignore diff --git a/couchbase-sdk-spring-service/src/main/resources/application.properties b/core-java/0.12457740242410742 similarity index 100% rename from couchbase-sdk-spring-service/src/main/resources/application.properties rename to core-java/0.12457740242410742 diff --git a/core-java/README.md b/core-java/README.md index 23fe12465f..49317bf369 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -13,3 +13,27 @@ - [Java – Write to File](http://www.baeldung.com/java-write-to-file) - [Java Scanner](http://www.baeldung.com/java-scanner) - [Java Timer](http://www.baeldung.com/java-timer-and-timertask) +- [Java – Byte Array to Writer](http://www.baeldung.com/java-convert-byte-array-to-writer) +- [How to Run a Shell Command in Java](http://www.baeldung.com/run-shell-command-in-java) +- [MD5 Hashing in Java](http://www.baeldung.com/java-md5) +- [Guide to the Java ArrayList](http://www.baeldung.com/java-arraylist) +- [Guide to Java Reflection](http://www.baeldung.com/java-reflection) +- [A Guide to Java Sockets](http://www.baeldung.com/a-guide-to-java-sockets) +- [Java 8 Collectors](http://www.baeldung.com/java-8-collectors) +- [Guide To CompletableFuture](http://www.baeldung.com/java-completablefuture) +- [Guide to Java 8’s Functional Interfaces](http://www.baeldung.com/java-8-functional-interfaces) +- [Convert char to String in Java](http://www.baeldung.com/java-convert-char-to-string) +- [Random List Element](http://www.baeldung.com/java-random-list-element) +- [Convert String to int or Integer in Java](http://www.baeldung.com/java-convert-string-to-int-or-integer) +- [Java 8 – Powerful Comparison with Lambdas](http://www.baeldung.com/java-8-sort-lambda) +- [Java – Directory Size](http://www.baeldung.com/java-folder-size) +- [Java – Try with Resources](http://www.baeldung.com/java-try-with-resources) +- [A Guide to the Java ExecutorService](http://www.baeldung.com/java-executor-service-tutorial) +- [Java 8 New Features](http://www.baeldung.com/java-8-new-features) +- [Lambda Expressions and Functional Interfaces: Tips and Best Practices](http://www.baeldung.com/java-8-lambda-expressions-tips) +- [The Double Colon Operator in Java 8](http://www.baeldung.com/java-8-double-colon-operator) +- [Java 8 Streams Advanced](http://www.baeldung.com/java-8-streams) +- [Introduction to Thread Pools in Java](http://www.baeldung.com/thread-pool-java-and-guava) +- [Introduction to Java 8 Streams](http://www.baeldung.com/java-8-streams-introduction) +- [Guide to the Fork/Join Framework in Java](http://www.baeldung.com/java-fork-join) +- [How to Print Screen in Java](http://www.baeldung.com/print-screen-in-java) diff --git a/core-java/pom.xml b/core-java/pom.xml index bc533607e7..8b93e238eb 100644 --- a/core-java/pom.xml +++ b/core-java/pom.xml @@ -1,205 +1,358 @@ - - 4.0.0 - com.baeldung - core-java - 0.1.0-SNAPSHOT + + 4.0.0 + com.baeldung + core-java + 0.1.0-SNAPSHOT + jar - core-java + core-java - + - - - net.sourceforge.collections - collections-generic - 4.01 - - - com.google.guava - guava - ${guava.version} - + + + net.sourceforge.collections + collections-generic + 4.01 + + + com.google.guava + guava + ${guava.version} + - - org.apache.commons - commons-collections4 - 4.0 - + + org.apache.commons + commons-collections4 + 4.0 + - - commons-io - commons-io - 2.4 - + + commons-io + commons-io + 2.4 + - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + - - org.apache.commons - commons-math3 - 3.3 - + + org.apache.commons + commons-math3 + 3.3 + - + - + - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - + + com.fasterxml.jackson.core + jackson-databind + ${jackson.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} - + + 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.assertj - assertj-core - ${assertj.version} - test - + + org.assertj + assertj-core + ${assertj.version} + test + - - org.testng - testng - ${testng.version} - test - + + org.testng + testng + ${testng.version} + test + - - org.mockito - mockito-core - ${mockito.version} - test - + + org.mockito + mockito-core + ${mockito.version} + test + - + + commons-codec + commons-codec + 1.10 + - - core-java - - - src/main/resources - true - - + - + + core-java + + + src/main/resources + true + + - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - 1.8 - 1.8 - - + - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - **/*IntegrationTest.java - - - + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + - + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + **/*IntegrationTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + + + - + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/libs + + + + - - - 4.3.11.Final - 5.1.38 + + org.apache.maven.plugins + maven-jar-plugin + + + + true + libs/ + org.baeldung.executable.ExecutableMavenJar + + + + - - 2.7.2 + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + + + org.baeldung.executable.ExecutableMavenJar + + + + jar-with-dependencies + + + + + - - 1.7.13 - 1.1.3 + + org.apache.maven.plugins + maven-shade-plugin + + + + shade + + + true + + + org.baeldung.executable.ExecutableMavenJar + + + + + + - - 5.1.3.Final + + com.jolira + onejar-maven-plugin + + + + org.baeldung.executable.ExecutableMavenJar + true + ${project.build.finalName}-onejar.${project.packaging} + + + one-jar + + + + - - 19.0 - 3.4 + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + spring-boot + org.baeldung.executable.ExecutableMavenJar + + + + + + - - 1.3 - 4.12 - 1.10.19 - 6.8 - 3.5.1 + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*ManualTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + - 4.4.1 - 4.5 + + + 4.3.11.Final + 5.1.38 - 2.9.0 + + 2.7.8 - - 3.5.1 - 2.6 - 2.19.1 - 2.7 - 1.4.18 + + 1.7.13 + 1.1.3 - + + 5.1.3.Final + + + 19.0 + 3.4 + + + 1.3 + 4.12 + 1.10.19 + 6.8 + 3.5.1 + + 4.4.1 + 4.5 + + 2.9.0 + + + 3.5.1 + 2.6 + 2.19.1 + 2.7 + 1.4.18 + + \ No newline at end of file diff --git a/spring-security-rest-custom/.gitignore b/core-java/src/main/java/com/baeldung/.gitignore similarity index 100% rename from spring-security-rest-custom/.gitignore rename to core-java/src/main/java/com/baeldung/.gitignore diff --git a/core-java-8/src/main/java/com/baeldung/Adder.java b/core-java/src/main/java/com/baeldung/Adder.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/Adder.java rename to core-java/src/main/java/com/baeldung/Adder.java diff --git a/core-java-8/src/main/java/com/baeldung/AdderImpl.java b/core-java/src/main/java/com/baeldung/AdderImpl.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/AdderImpl.java rename to core-java/src/main/java/com/baeldung/AdderImpl.java diff --git a/core-java-8/src/main/java/com/baeldung/Bar.java b/core-java/src/main/java/com/baeldung/Bar.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/Bar.java rename to core-java/src/main/java/com/baeldung/Bar.java diff --git a/core-java-8/src/main/java/com/baeldung/Baz.java b/core-java/src/main/java/com/baeldung/Baz.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/Baz.java rename to core-java/src/main/java/com/baeldung/Baz.java diff --git a/core-java-8/src/main/java/com/baeldung/Foo.java b/core-java/src/main/java/com/baeldung/Foo.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/Foo.java rename to core-java/src/main/java/com/baeldung/Foo.java diff --git a/core-java-8/src/main/java/com/baeldung/FooExtended.java b/core-java/src/main/java/com/baeldung/FooExtended.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/FooExtended.java rename to core-java/src/main/java/com/baeldung/FooExtended.java diff --git a/core-java-8/src/main/java/com/baeldung/UseFoo.java b/core-java/src/main/java/com/baeldung/UseFoo.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/UseFoo.java rename to core-java/src/main/java/com/baeldung/UseFoo.java diff --git a/core-java/src/main/java/com/baeldung/datetime/README.md b/core-java/src/main/java/com/baeldung/datetime/README.md new file mode 100644 index 0000000000..1e4adbb612 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/datetime/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Introduction to the Java 8 Date/Time API](http://www.baeldung.com/java-8-date-time-intro) diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseDuration.java b/core-java/src/main/java/com/baeldung/datetime/UseDuration.java similarity index 74% rename from core-java-8/src/main/java/com/baeldung/datetime/UseDuration.java rename to core-java/src/main/java/com/baeldung/datetime/UseDuration.java index 125b6fbe38..31b45aab84 100644 --- a/core-java-8/src/main/java/com/baeldung/datetime/UseDuration.java +++ b/core-java/src/main/java/com/baeldung/datetime/UseDuration.java @@ -5,12 +5,12 @@ import java.time.LocalTime; import java.time.Period; public class UseDuration { - - public LocalTime modifyDates(LocalTime localTime,Duration duration){ + + public LocalTime modifyDates(LocalTime localTime, Duration duration) { return localTime.plus(duration); } - - public Duration getDifferenceBetweenDates(LocalTime localTime1,LocalTime localTime2){ + + public Duration getDifferenceBetweenDates(LocalTime localTime1, LocalTime localTime2) { return Duration.between(localTime1, localTime2); } } diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDate.java b/core-java/src/main/java/com/baeldung/datetime/UseLocalDate.java similarity index 67% rename from core-java-8/src/main/java/com/baeldung/datetime/UseLocalDate.java rename to core-java/src/main/java/com/baeldung/datetime/UseLocalDate.java index 47b1b3f67d..82f5745b3c 100644 --- a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDate.java +++ b/core-java/src/main/java/com/baeldung/datetime/UseLocalDate.java @@ -7,39 +7,39 @@ import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAdjusters; public class UseLocalDate { - - public LocalDate getLocalDateUsingFactoryOfMethod(int year, int month, int dayOfMonth){ + + public LocalDate getLocalDateUsingFactoryOfMethod(int year, int month, int dayOfMonth) { return LocalDate.of(year, month, dayOfMonth); } - - public LocalDate getLocalDateUsingParseMethod(String representation){ + + public LocalDate getLocalDateUsingParseMethod(String representation) { return LocalDate.parse(representation); } - - public LocalDate getLocalDateFromClock(){ + + public LocalDate getLocalDateFromClock() { LocalDate localDate = LocalDate.now(); return localDate; } - - public LocalDate getNextDay(LocalDate localDate){ + + public LocalDate getNextDay(LocalDate localDate) { return localDate.plusDays(1); } - - public LocalDate getPreviousDay(LocalDate localDate){ + + public LocalDate getPreviousDay(LocalDate localDate) { return localDate.minus(1, ChronoUnit.DAYS); } - - public DayOfWeek getDayOfWeek(LocalDate localDate){ + + public DayOfWeek getDayOfWeek(LocalDate localDate) { DayOfWeek day = localDate.getDayOfWeek(); return day; } - - public LocalDate getFirstDayOfMonth(){ + + public LocalDate getFirstDayOfMonth() { LocalDate firstDayOfMonth = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()); return firstDayOfMonth; } - - public LocalDateTime getStartOfDay(LocalDate localDate){ + + public LocalDateTime getStartOfDay(LocalDate localDate) { LocalDateTime startofDay = localDate.atStartOfDay(); return startofDay; } diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDateTime.java b/core-java/src/main/java/com/baeldung/datetime/UseLocalDateTime.java similarity index 87% rename from core-java-8/src/main/java/com/baeldung/datetime/UseLocalDateTime.java rename to core-java/src/main/java/com/baeldung/datetime/UseLocalDateTime.java index 7aa1eaa276..7f39ac2f91 100644 --- a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDateTime.java +++ b/core-java/src/main/java/com/baeldung/datetime/UseLocalDateTime.java @@ -3,8 +3,8 @@ package com.baeldung.datetime; import java.time.LocalDateTime; public class UseLocalDateTime { - - public LocalDateTime getLocalDateTimeUsingParseMethod(String representation){ + + public LocalDateTime getLocalDateTimeUsingParseMethod(String representation) { return LocalDateTime.parse(representation); } diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalTime.java b/core-java/src/main/java/com/baeldung/datetime/UseLocalTime.java similarity index 67% rename from core-java-8/src/main/java/com/baeldung/datetime/UseLocalTime.java rename to core-java/src/main/java/com/baeldung/datetime/UseLocalTime.java index e13fd10d6f..9bd8f9706c 100644 --- a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalTime.java +++ b/core-java/src/main/java/com/baeldung/datetime/UseLocalTime.java @@ -4,32 +4,32 @@ import java.time.LocalTime; import java.time.temporal.ChronoUnit; public class UseLocalTime { - - public LocalTime getLocalTimeUsingFactoryOfMethod(int hour, int min, int seconds){ + + public LocalTime getLocalTimeUsingFactoryOfMethod(int hour, int min, int seconds) { LocalTime localTime = LocalTime.of(hour, min, seconds); return localTime; } - - public LocalTime getLocalTimeUsingParseMethod(String timeRepresentation){ + + public LocalTime getLocalTimeUsingParseMethod(String timeRepresentation) { LocalTime localTime = LocalTime.parse(timeRepresentation); return localTime; } - - public LocalTime getLocalTimeFromClock(){ + + public LocalTime getLocalTimeFromClock() { LocalTime localTime = LocalTime.now(); return localTime; } - - public LocalTime addAnHour(LocalTime localTime){ - LocalTime newTime = localTime.plus(1,ChronoUnit.HOURS); + + public LocalTime addAnHour(LocalTime localTime) { + LocalTime newTime = localTime.plus(1, ChronoUnit.HOURS); return newTime; } - - public int getHourFromLocalTime(LocalTime localTime){ + + public int getHourFromLocalTime(LocalTime localTime) { return localTime.getHour(); } - - public LocalTime getLocalTimeWithMinuteSetToValue(LocalTime localTime, int minute){ + + public LocalTime getLocalTimeWithMinuteSetToValue(LocalTime localTime, int minute) { return localTime.withMinute(minute); } } diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UsePeriod.java b/core-java/src/main/java/com/baeldung/datetime/UsePeriod.java similarity index 73% rename from core-java-8/src/main/java/com/baeldung/datetime/UsePeriod.java rename to core-java/src/main/java/com/baeldung/datetime/UsePeriod.java index 326cfad650..5a42ef83b4 100644 --- a/core-java-8/src/main/java/com/baeldung/datetime/UsePeriod.java +++ b/core-java/src/main/java/com/baeldung/datetime/UsePeriod.java @@ -4,12 +4,12 @@ import java.time.LocalDate; import java.time.Period; public class UsePeriod { - - public LocalDate modifyDates(LocalDate localDate,Period period){ + + public LocalDate modifyDates(LocalDate localDate, Period period) { return localDate.plus(period); } - - public Period getDifferenceBetweenDates(LocalDate localDate1,LocalDate localDate2){ + + public Period getDifferenceBetweenDates(LocalDate localDate1, LocalDate localDate2) { return Period.between(localDate1, localDate2); } } diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseToInstant.java b/core-java/src/main/java/com/baeldung/datetime/UseToInstant.java similarity index 87% rename from core-java-8/src/main/java/com/baeldung/datetime/UseToInstant.java rename to core-java/src/main/java/com/baeldung/datetime/UseToInstant.java index 1ddb096cf6..94154ce5c0 100644 --- a/core-java-8/src/main/java/com/baeldung/datetime/UseToInstant.java +++ b/core-java/src/main/java/com/baeldung/datetime/UseToInstant.java @@ -6,13 +6,13 @@ import java.util.Calendar; import java.util.Date; public class UseToInstant { - - public LocalDateTime convertDateToLocalDate(Date date){ + + public LocalDateTime convertDateToLocalDate(Date date) { LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); return localDateTime; } - - public LocalDateTime convertDateToLocalDate(Calendar calendar){ + + public LocalDateTime convertDateToLocalDate(Calendar calendar) { LocalDateTime localDateTime = LocalDateTime.ofInstant(calendar.toInstant(), ZoneId.systemDefault()); return localDateTime; } diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseZonedDateTime.java b/core-java/src/main/java/com/baeldung/datetime/UseZonedDateTime.java similarity index 90% rename from core-java-8/src/main/java/com/baeldung/datetime/UseZonedDateTime.java rename to core-java/src/main/java/com/baeldung/datetime/UseZonedDateTime.java index 0369de9835..2d1b17484b 100644 --- a/core-java-8/src/main/java/com/baeldung/datetime/UseZonedDateTime.java +++ b/core-java/src/main/java/com/baeldung/datetime/UseZonedDateTime.java @@ -5,8 +5,8 @@ import java.time.ZoneId; import java.time.ZonedDateTime; public class UseZonedDateTime { - - public ZonedDateTime getZonedDateTime(LocalDateTime localDateTime,ZoneId zoneId){ + + public ZonedDateTime getZonedDateTime(LocalDateTime localDateTime, ZoneId zoneId) { ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, zoneId); return zonedDateTime; } diff --git a/core-java-8/src/main/java/com/baeldung/doublecolon/Computer.java b/core-java/src/main/java/com/baeldung/doublecolon/Computer.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/doublecolon/Computer.java rename to core-java/src/main/java/com/baeldung/doublecolon/Computer.java diff --git a/core-java-8/src/main/java/com/baeldung/doublecolon/ComputerUtils.java b/core-java/src/main/java/com/baeldung/doublecolon/ComputerUtils.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/doublecolon/ComputerUtils.java rename to core-java/src/main/java/com/baeldung/doublecolon/ComputerUtils.java diff --git a/core-java-8/src/main/java/com/baeldung/doublecolon/MacbookPro.java b/core-java/src/main/java/com/baeldung/doublecolon/MacbookPro.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/doublecolon/MacbookPro.java rename to core-java/src/main/java/com/baeldung/doublecolon/MacbookPro.java diff --git a/core-java-8/src/main/java/com/baeldung/doublecolon/function/ComputerPredicate.java b/core-java/src/main/java/com/baeldung/doublecolon/function/ComputerPredicate.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/doublecolon/function/ComputerPredicate.java rename to core-java/src/main/java/com/baeldung/doublecolon/function/ComputerPredicate.java diff --git a/core-java-8/src/main/java/com/baeldung/doublecolon/function/TriFunction.java b/core-java/src/main/java/com/baeldung/doublecolon/function/TriFunction.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/doublecolon/function/TriFunction.java rename to core-java/src/main/java/com/baeldung/doublecolon/function/TriFunction.java diff --git a/core-java/src/main/java/com/baeldung/enums/Pizza.java b/core-java/src/main/java/com/baeldung/enums/Pizza.java index 7742781081..bad134bf00 100644 --- a/core-java/src/main/java/com/baeldung/enums/Pizza.java +++ b/core-java/src/main/java/com/baeldung/enums/Pizza.java @@ -1,11 +1,5 @@ package com.baeldung.enums; -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.commons.collections15.Predicate; - -import java.io.IOException; import java.util.EnumMap; import java.util.EnumSet; import java.util.List; @@ -13,13 +7,11 @@ import java.util.stream.Collectors; public class Pizza { - private static EnumSet undeliveredPizzaStatuses = - EnumSet.of(PizzaStatus.ORDERED, PizzaStatus.READY); + private static EnumSet deliveredPizzaStatuses = EnumSet.of(PizzaStatusEnum.DELIVERED); - private PizzaStatus status; + private PizzaStatusEnum status; - @JsonFormat(shape = JsonFormat.Shape.OBJECT) - public enum PizzaStatus { + public enum PizzaStatusEnum { ORDERED(5) { @Override public boolean isOrdered() { @@ -53,21 +45,20 @@ public class Pizza { return false; } - @JsonProperty("timeToDelivery") public int getTimeToDelivery() { return timeToDelivery; } - PizzaStatus(int timeToDelivery) { + PizzaStatusEnum(int timeToDelivery) { this.timeToDelivery = timeToDelivery; } } - public PizzaStatus getStatus() { + public PizzaStatusEnum getStatus() { return status; } - public void setStatus(PizzaStatus status) { + public void setStatus(PizzaStatusEnum status) { this.status = status; } @@ -80,31 +71,18 @@ public class Pizza { } public static List getAllUndeliveredPizzas(List input) { - return input.stream().filter( - (s) -> undeliveredPizzaStatuses.contains(s.getStatus())) - .collect(Collectors.toList()); + return input.stream().filter((s) -> !deliveredPizzaStatuses.contains(s.getStatus())).collect(Collectors.toList()); } - public static EnumMap> - groupPizzaByStatus(List pzList) { - return pzList.stream().collect( - Collectors.groupingBy(Pizza::getStatus, - () -> new EnumMap<>(PizzaStatus.class), Collectors.toList())); + public static EnumMap> groupPizzaByStatus(List pzList) { + return pzList.stream().collect(Collectors.groupingBy(Pizza::getStatus, () -> new EnumMap<>(PizzaStatusEnum.class), Collectors.toList())); } public void deliver() { if (isDeliverable()) { PizzaDeliverySystemConfiguration.getInstance().getDeliveryStrategy().deliver(this); - this.setStatus(PizzaStatus.DELIVERED); + this.setStatus(PizzaStatusEnum.DELIVERED); } } - public static String getJsonString(Pizza pz) throws IOException { - ObjectMapper mapper = new ObjectMapper(); - return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(pz); - } - - private static Predicate thatAreNotDelivered() { - return entry -> undeliveredPizzaStatuses.contains(entry.getStatus()); - } } \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/enums/README.md b/core-java/src/main/java/com/baeldung/enums/README.md new file mode 100644 index 0000000000..6ccfa725f5 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/enums/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [A Guide to Java Enums](http://www.baeldung.com/a-guide-to-java-enums) diff --git a/core-java/src/main/java/com/baeldung/equalshashcode/entities/ComplexClass.java b/core-java/src/main/java/com/baeldung/equalshashcode/entities/ComplexClass.java new file mode 100644 index 0000000000..5a13f505c2 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/equalshashcode/entities/ComplexClass.java @@ -0,0 +1,63 @@ +package com.baeldung.equalshashcode.entities; + +import java.util.List; +import java.util.Set; + +public class ComplexClass { + + private List genericList; + private Set integerSet; + + public ComplexClass(List genericArrayList, Set integerHashSet) { + super(); + this.genericList = genericArrayList; + this.integerSet = integerHashSet; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((genericList == null) ? 0 : genericList.hashCode()); + result = prime * result + ((integerSet == null) ? 0 : integerSet.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof ComplexClass)) + return false; + ComplexClass other = (ComplexClass) obj; + if (genericList == null) { + if (other.genericList != null) + return false; + } else if (!genericList.equals(other.genericList)) + return false; + if (integerSet == null) { + if (other.integerSet != null) + return false; + } else if (!integerSet.equals(other.integerSet)) + return false; + return true; + } + + protected List getGenericList() { + return genericList; + } + + protected void setGenericArrayList(List genericList) { + this.genericList = genericList; + } + + protected Set getIntegerSet() { + return integerSet; + } + + protected void setIntegerSet(Set integerSet) { + this.integerSet = integerSet; + } +} diff --git a/core-java/src/main/java/com/baeldung/equalshashcode/entities/PrimitiveClass.java b/core-java/src/main/java/com/baeldung/equalshashcode/entities/PrimitiveClass.java new file mode 100644 index 0000000000..29b280865e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/equalshashcode/entities/PrimitiveClass.java @@ -0,0 +1,54 @@ +package com.baeldung.equalshashcode.entities; + +public class PrimitiveClass { + + private boolean primitiveBoolean; + private int primitiveInt; + + public PrimitiveClass(boolean primitiveBoolean, int primitiveInt) { + super(); + this.primitiveBoolean = primitiveBoolean; + this.primitiveInt = primitiveInt; + } + + protected boolean isPrimitiveBoolean() { + return primitiveBoolean; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (primitiveBoolean ? 1231 : 1237); + result = prime * result + primitiveInt; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PrimitiveClass other = (PrimitiveClass) obj; + if (primitiveBoolean != other.primitiveBoolean) + return false; + if (primitiveInt != other.primitiveInt) + return false; + return true; + } + + protected void setPrimitiveBoolean(boolean primitiveBoolean) { + this.primitiveBoolean = primitiveBoolean; + } + + protected int getPrimitiveInt() { + return primitiveInt; + } + + protected void setPrimitiveInt(int primitiveInt) { + this.primitiveInt = primitiveInt; + } +} diff --git a/core-java/src/main/java/com/baeldung/equalshashcode/entities/Rectangle.java b/core-java/src/main/java/com/baeldung/equalshashcode/entities/Rectangle.java new file mode 100644 index 0000000000..168e3af0c6 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/equalshashcode/entities/Rectangle.java @@ -0,0 +1,58 @@ +package com.baeldung.equalshashcode.entities; + +public class Rectangle extends Shape { + private double width; + private double length; + + public Rectangle(double width, double length) { + this.width = width; + this.length = length; + } + + @Override + public double area() { + return width * length; + } + + @Override + public double perimeter() { + return 2 * (width + length); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + long temp; + temp = Double.doubleToLongBits(length); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(width); + result = prime * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Rectangle other = (Rectangle) obj; + if (Double.doubleToLongBits(length) != Double.doubleToLongBits(other.length)) + return false; + if (Double.doubleToLongBits(width) != Double.doubleToLongBits(other.width)) + return false; + return true; + } + + protected double getWidth() { + return width; + } + + protected double getLength() { + return length; + } + +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/equalshashcode/entities/Shape.java b/core-java/src/main/java/com/baeldung/equalshashcode/entities/Shape.java new file mode 100644 index 0000000000..628359becf --- /dev/null +++ b/core-java/src/main/java/com/baeldung/equalshashcode/entities/Shape.java @@ -0,0 +1,7 @@ +package com.baeldung.equalshashcode.entities; + +public abstract class Shape { + public abstract double area(); + + public abstract double perimeter(); +} diff --git a/core-java/src/main/java/com/baeldung/equalshashcode/entities/Square.java b/core-java/src/main/java/com/baeldung/equalshashcode/entities/Square.java new file mode 100644 index 0000000000..b9125c3e2f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/equalshashcode/entities/Square.java @@ -0,0 +1,58 @@ +package com.baeldung.equalshashcode.entities; + +import java.awt.Color; + +public class Square extends Rectangle { + + Color color; + + public Square(double width, Color color) { + super(width, width); + this.color = color; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((color == null) ? 0 : color.hashCode()); + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof Square)) { + return false; + } + Square other = (Square) obj; + if (color == null) { + if (other.color != null) { + return false; + } + } else if (!color.equals(other.color)) { + return false; + } + return true; + } + + protected Color getColor() { + return color; + } + + protected void setColor(Color color) { + this.color = color; + } + +} diff --git a/core-java/src/main/java/com/baeldung/executable/ExecutableMavenJar.java b/core-java/src/main/java/com/baeldung/executable/ExecutableMavenJar.java new file mode 100644 index 0000000000..6c79e89717 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/executable/ExecutableMavenJar.java @@ -0,0 +1,11 @@ +package com.baeldung.executable; + +import javax.swing.JOptionPane; + +public class ExecutableMavenJar { + + public static void main(String[] args) { + JOptionPane.showMessageDialog(null, "It worked!", "Executable Jar with Maven", 1); + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/forkjoin/CustomRecursiveAction.java b/core-java/src/main/java/com/baeldung/forkjoin/CustomRecursiveAction.java similarity index 94% rename from core-java-8/src/main/java/com/baeldung/forkjoin/CustomRecursiveAction.java rename to core-java/src/main/java/com/baeldung/forkjoin/CustomRecursiveAction.java index f1ab2d8d09..ae79787570 100644 --- a/core-java-8/src/main/java/com/baeldung/forkjoin/CustomRecursiveAction.java +++ b/core-java/src/main/java/com/baeldung/forkjoin/CustomRecursiveAction.java @@ -30,8 +30,7 @@ public class CustomRecursiveAction extends RecursiveAction { private Collection createSubtasks() { - List subtasks = - new ArrayList<>(); + List subtasks = new ArrayList<>(); String partOne = workLoad.substring(0, workLoad.length() / 2); String partTwo = workLoad.substring(workLoad.length() / 2, workLoad.length()); diff --git a/core-java-8/src/main/java/com/baeldung/forkjoin/CustomRecursiveTask.java b/core-java/src/main/java/com/baeldung/forkjoin/CustomRecursiveTask.java similarity index 60% rename from core-java-8/src/main/java/com/baeldung/forkjoin/CustomRecursiveTask.java rename to core-java/src/main/java/com/baeldung/forkjoin/CustomRecursiveTask.java index 5d4d97b805..af9805c33f 100644 --- a/core-java-8/src/main/java/com/baeldung/forkjoin/CustomRecursiveTask.java +++ b/core-java/src/main/java/com/baeldung/forkjoin/CustomRecursiveTask.java @@ -1,6 +1,5 @@ package com.baeldung.forkjoin; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -23,10 +22,7 @@ public class CustomRecursiveTask extends RecursiveTask { if (arr.length > THRESHOLD) { - return ForkJoinTask.invokeAll(createSubtasks()) - .stream() - .mapToInt(ForkJoinTask::join) - .sum(); + return ForkJoinTask.invokeAll(createSubtasks()).stream().mapToInt(ForkJoinTask::join).sum(); } else { return processing(arr); @@ -35,17 +31,12 @@ public class CustomRecursiveTask extends RecursiveTask { private Collection createSubtasks() { List dividedTasks = new ArrayList<>(); - dividedTasks.add(new CustomRecursiveTask( - Arrays.copyOfRange(arr, 0, arr.length / 2))); - dividedTasks.add(new CustomRecursiveTask( - Arrays.copyOfRange(arr, arr.length / 2, arr.length))); + dividedTasks.add(new CustomRecursiveTask(Arrays.copyOfRange(arr, 0, arr.length / 2))); + dividedTasks.add(new CustomRecursiveTask(Arrays.copyOfRange(arr, arr.length / 2, arr.length))); return dividedTasks; } private Integer processing(int[] arr) { - return Arrays.stream(arr) - .filter(a -> a > 10 && a < 27) - .map(a -> a * 10) - .sum(); + return Arrays.stream(arr).filter(a -> a > 10 && a < 27).map(a -> a * 10).sum(); } } diff --git a/core-java-8/src/main/java/com/baeldung/forkjoin/util/PoolUtil.java b/core-java/src/main/java/com/baeldung/forkjoin/util/PoolUtil.java similarity index 99% rename from core-java-8/src/main/java/com/baeldung/forkjoin/util/PoolUtil.java rename to core-java/src/main/java/com/baeldung/forkjoin/util/PoolUtil.java index 521616600f..fd24a6fc66 100644 --- a/core-java-8/src/main/java/com/baeldung/forkjoin/util/PoolUtil.java +++ b/core-java/src/main/java/com/baeldung/forkjoin/util/PoolUtil.java @@ -1,6 +1,5 @@ package com.baeldung.forkjoin.util; - import java.util.concurrent.ForkJoinPool; public class PoolUtil { diff --git a/core-java/src/main/java/com/baeldung/java/conversion/StringConversion.java b/core-java/src/main/java/com/baeldung/java/conversion/StringConversion.java new file mode 100644 index 0000000000..0a0f79566e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/conversion/StringConversion.java @@ -0,0 +1,60 @@ +package com.baeldung.java.conversion; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.util.Date; + +import com.baeldung.datetime.UseLocalDateTime; + +public class StringConversion { + + public static int getInt(String str) { + return Integer.parseInt(str); + } + + public static int getInteger(String str) { + return Integer.valueOf(str); + } + + public static long getLongPrimitive(String str) { + return Long.parseLong(str); + } + + public static Long getLong(String str) { + return Long.valueOf(str); + } + + public static double getDouble(String str) { + return Double.parseDouble(str); + } + + public static double getDoublePrimitive(String str) { + return Double.valueOf(str); + } + + public static byte[] getByteArray(String str) { + return str.getBytes(); + } + + public static char[] getCharArray(String str) { + return str.toCharArray(); + } + + public static boolean getBooleanPrimitive(String str) { + return Boolean.parseBoolean(str); + } + + public static boolean getBoolean(String str) { + return Boolean.valueOf(str); + } + + public static Date getJava6Date(String str, String format) throws ParseException { + SimpleDateFormat formatter = new SimpleDateFormat(format); + return formatter.parse(str); + } + + public static LocalDateTime getJava8Date(String str) throws ParseException { + return new UseLocalDateTime().getLocalDateTimeUsingParseMethod(str); + } +} diff --git a/core-java/src/main/java/com/baeldung/java/networking/cookies/PersistentCookieStore.java b/core-java/src/main/java/com/baeldung/java/networking/cookies/PersistentCookieStore.java new file mode 100644 index 0000000000..0d66406ac2 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/networking/cookies/PersistentCookieStore.java @@ -0,0 +1,56 @@ +package com.baeldung.java.networking.cookies; + +import java.net.*; +import java.util.List; + +public class PersistentCookieStore implements CookieStore, Runnable { + CookieStore store; + + public PersistentCookieStore() { + store = new CookieManager().getCookieStore(); + // deserialize cookies into store + Runtime.getRuntime().addShutdownHook(new Thread(this)); + } + + @Override + public void run() { + // serialize cookies to persistent storage + } + + @Override + public void add(URI uri, HttpCookie cookie) { + store.add(uri, cookie); + + } + + @Override + public List get(URI uri) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getCookies() { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getURIs() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean remove(URI uri, HttpCookie cookie) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean removeAll() { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/core-java/src/main/java/com/baeldung/java/networking/cookies/ProxyAcceptCookiePolicy.java b/core-java/src/main/java/com/baeldung/java/networking/cookies/ProxyAcceptCookiePolicy.java new file mode 100644 index 0000000000..6d6371bfe0 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/networking/cookies/ProxyAcceptCookiePolicy.java @@ -0,0 +1,26 @@ +package com.baeldung.java.networking.cookies; + +import java.net.*; + +public class ProxyAcceptCookiePolicy implements CookiePolicy { + String acceptedProxy; + + public ProxyAcceptCookiePolicy(String acceptedProxy) { + this.acceptedProxy = acceptedProxy; + } + + public boolean shouldAccept(URI uri, HttpCookie cookie) { + String host; + try { + host = InetAddress.getByName(uri.getHost()).getCanonicalHostName(); + } catch (UnknownHostException e) { + host = uri.getHost(); + } + + if (!HttpCookie.domainMatches(acceptedProxy, host)) { + return false; + } + + return CookiePolicy.ACCEPT_ORIGINAL_SERVER.shouldAccept(uri, cookie); + } +} diff --git a/core-java/src/main/java/com/baeldung/java/networking/udp/EchoClient.java b/core-java/src/main/java/com/baeldung/java/networking/udp/EchoClient.java new file mode 100644 index 0000000000..916442533b --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/networking/udp/EchoClient.java @@ -0,0 +1,42 @@ +package com.baeldung.java.networking.udp; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; + +public class EchoClient { + private DatagramSocket socket; + private InetAddress address; + + private byte[] buf; + + public EchoClient() { + try { + socket = new DatagramSocket(); + address = InetAddress.getByName("localhost"); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public String sendEcho(String msg) { + DatagramPacket packet = null; + try { + buf = msg.getBytes(); + packet = new DatagramPacket(buf, buf.length, address, 4445); + socket.send(packet); + packet = new DatagramPacket(buf, buf.length); + socket.receive(packet); + } catch (IOException e) { + e.printStackTrace(); + } + String received = new String(packet.getData(), 0, packet.getLength()); + return received; + } + + public void close() { + socket.close(); + } +} diff --git a/core-java/src/main/java/com/baeldung/java/networking/udp/EchoServer.java b/core-java/src/main/java/com/baeldung/java/networking/udp/EchoServer.java new file mode 100644 index 0000000000..900d330786 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/networking/udp/EchoServer.java @@ -0,0 +1,42 @@ +package com.baeldung.java.networking.udp; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; + +public class EchoServer extends Thread { + + protected DatagramSocket socket = null; + protected boolean running; + protected byte[] buf = new byte[256]; + + public EchoServer() throws IOException { + socket = new DatagramSocket(4445); + } + + public void run() { + running = true; + + while (running) { + try { + + DatagramPacket packet = new DatagramPacket(buf, buf.length); + socket.receive(packet); + InetAddress address = packet.getAddress(); + int port = packet.getPort(); + packet = new DatagramPacket(buf, buf.length, address, port); + String received = new String(packet.getData(), 0, packet.getLength()); + if (received.equals("end")) { + running = false; + continue; + } + socket.send(packet); + } catch (IOException e) { + e.printStackTrace(); + running = false; + } + } + socket.close(); + } +} diff --git a/core-java/src/main/java/com/baeldung/java/nio/selector/EchoClient.java b/core-java/src/main/java/com/baeldung/java/nio/selector/EchoClient.java new file mode 100644 index 0000000000..61f339db58 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/nio/selector/EchoClient.java @@ -0,0 +1,50 @@ +package com.baeldung.java.nio.selector; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SocketChannel; + +public class EchoClient { + private static SocketChannel client; + private static ByteBuffer buffer; + private static EchoClient instance; + + public static EchoClient start() { + if (instance == null) + instance = new EchoClient(); + + return instance; + } + + public static void stop() throws IOException { + client.close(); + buffer = null; + } + + private EchoClient() { + try { + client = SocketChannel.open(new InetSocketAddress("localhost", 5454)); + buffer = ByteBuffer.allocate(256); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public String sendMessage(String msg) { + buffer = ByteBuffer.wrap(msg.getBytes()); + String response = null; + try { + client.write(buffer); + buffer.clear(); + client.read(buffer); + response = new String(buffer.array()).trim(); + System.out.println("response=" + response); + buffer.clear(); + } catch (IOException e) { + e.printStackTrace(); + } + return response; + + } +} diff --git a/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java b/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java new file mode 100644 index 0000000000..2ed9a27c4c --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java @@ -0,0 +1,60 @@ +package com.baeldung.java.nio.selector; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.Iterator; +import java.util.Set; + +public class EchoServer { + + public static void main(String[] args) throws IOException { + Selector selector = Selector.open(); + ServerSocketChannel serverSocket = ServerSocketChannel.open(); + serverSocket.bind(new InetSocketAddress("localhost", 5454)); + serverSocket.configureBlocking(false); + serverSocket.register(selector, SelectionKey.OP_ACCEPT); + ByteBuffer buffer = ByteBuffer.allocate(256); + + while (true) { + selector.select(); + Set selectedKeys = selector.selectedKeys(); + Iterator iter = selectedKeys.iterator(); + while (iter.hasNext()) { + + SelectionKey key = iter.next(); + + if (key.isAcceptable()) { + SocketChannel client = serverSocket.accept(); + client.configureBlocking(false); + client.register(selector, SelectionKey.OP_READ); + } + + if (key.isReadable()) { + SocketChannel client = (SocketChannel) key.channel(); + client.read(buffer); + buffer.flip(); + client.write(buffer); + buffer.clear(); + } + iter.remove(); + } + } + } + + public static Process start() throws IOException, InterruptedException { + String javaHome = System.getProperty("java.home"); + String javaBin = javaHome + File.separator + "bin" + File.separator + "java"; + String classpath = System.getProperty("java.class.path"); + String className = EchoServer.class.getCanonicalName(); + + ProcessBuilder builder = new ProcessBuilder(javaBin, "-cp", classpath, className); + + return builder.start(); + } +} diff --git a/core-java/src/main/java/com/baeldung/java/reflection/Animal.java b/core-java/src/main/java/com/baeldung/java/reflection/Animal.java new file mode 100644 index 0000000000..3f36243c29 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/reflection/Animal.java @@ -0,0 +1,23 @@ +package com.baeldung.java.reflection; + +public abstract class Animal implements Eating { + + public static final String CATEGORY = "domestic"; + + private String name; + + public Animal(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + protected abstract String getSound(); + +} diff --git a/core-java/src/main/java/com/baeldung/java/reflection/Bird.java b/core-java/src/main/java/com/baeldung/java/reflection/Bird.java new file mode 100644 index 0000000000..bd6f13094c --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/reflection/Bird.java @@ -0,0 +1,36 @@ +package com.baeldung.java.reflection; + +public class Bird extends Animal { + private boolean walks; + + public Bird() { + super("bird"); + } + + public Bird(String name, boolean walks) { + super(name); + setWalks(walks); + } + + public Bird(String name) { + super(name); + } + + @Override + public String eats() { + return "grains"; + } + + @Override + protected String getSound() { + return "chaps"; + } + + public boolean walks() { + return walks; + } + + public void setWalks(boolean walks) { + this.walks = walks; + } +} diff --git a/core-java/src/main/java/com/baeldung/java/reflection/Eating.java b/core-java/src/main/java/com/baeldung/java/reflection/Eating.java new file mode 100644 index 0000000000..479425cad4 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/reflection/Eating.java @@ -0,0 +1,5 @@ +package com.baeldung.java.reflection; + +public interface Eating { + String eats(); +} diff --git a/core-java/src/main/java/com/baeldung/java/reflection/Goat.java b/core-java/src/main/java/com/baeldung/java/reflection/Goat.java new file mode 100644 index 0000000000..503717ae5e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/reflection/Goat.java @@ -0,0 +1,24 @@ +package com.baeldung.java.reflection; + +public class Goat extends Animal implements Locomotion { + + public Goat(String name) { + super(name); + } + + @Override + protected String getSound() { + return "bleat"; + } + + @Override + public String getLocomotion() { + return "walks"; + } + + @Override + public String eats() { + return "grass"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/java/reflection/Locomotion.java b/core-java/src/main/java/com/baeldung/java/reflection/Locomotion.java new file mode 100644 index 0000000000..047c00cb13 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/reflection/Locomotion.java @@ -0,0 +1,5 @@ +package com.baeldung.java.reflection; + +public interface Locomotion { + String getLocomotion(); +} diff --git a/core-java/src/main/java/com/baeldung/java/reflection/Person.java b/core-java/src/main/java/com/baeldung/java/reflection/Person.java new file mode 100644 index 0000000000..f3d7f9f001 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/reflection/Person.java @@ -0,0 +1,6 @@ +package com.baeldung.java.reflection; + +public class Person { + private String name; + private int age; +} diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/Address.java b/core-java/src/main/java/com/baeldung/java_8_features/Address.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/java_8_features/Address.java rename to core-java/src/main/java/com/baeldung/java_8_features/Address.java diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/CustomException.java b/core-java/src/main/java/com/baeldung/java_8_features/CustomException.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/java_8_features/CustomException.java rename to core-java/src/main/java/com/baeldung/java_8_features/CustomException.java diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/Detail.java b/core-java/src/main/java/com/baeldung/java_8_features/Detail.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/java_8_features/Detail.java rename to core-java/src/main/java/com/baeldung/java_8_features/Detail.java diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/OptionalAddress.java b/core-java/src/main/java/com/baeldung/java_8_features/OptionalAddress.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/java_8_features/OptionalAddress.java rename to core-java/src/main/java/com/baeldung/java_8_features/OptionalAddress.java diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/OptionalUser.java b/core-java/src/main/java/com/baeldung/java_8_features/OptionalUser.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/java_8_features/OptionalUser.java rename to core-java/src/main/java/com/baeldung/java_8_features/OptionalUser.java diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/User.java b/core-java/src/main/java/com/baeldung/java_8_features/User.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/java_8_features/User.java rename to core-java/src/main/java/com/baeldung/java_8_features/User.java diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/Vehicle.java b/core-java/src/main/java/com/baeldung/java_8_features/Vehicle.java similarity index 89% rename from core-java-8/src/main/java/com/baeldung/java_8_features/Vehicle.java rename to core-java/src/main/java/com/baeldung/java_8_features/Vehicle.java index 011173bcaf..045fc90590 100644 --- a/core-java-8/src/main/java/com/baeldung/java_8_features/Vehicle.java +++ b/core-java/src/main/java/com/baeldung/java_8_features/Vehicle.java @@ -9,7 +9,7 @@ public interface Vehicle { } default long[] startPosition() { - return new long[]{23, 15}; + return new long[] { 23, 15 }; } default String getOverview() { diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/VehicleImpl.java b/core-java/src/main/java/com/baeldung/java_8_features/VehicleImpl.java similarity index 63% rename from core-java-8/src/main/java/com/baeldung/java_8_features/VehicleImpl.java rename to core-java/src/main/java/com/baeldung/java_8_features/VehicleImpl.java index 83e55f5f4d..64bec0246d 100644 --- a/core-java-8/src/main/java/com/baeldung/java_8_features/VehicleImpl.java +++ b/core-java/src/main/java/com/baeldung/java_8_features/VehicleImpl.java @@ -1,9 +1,9 @@ package com.baeldung.java_8_features; -public class VehicleImpl implements Vehicle { +public class VehicleImpl implements Vehicle { @Override public void moveTo(long altitude, long longitude) { - //do nothing + // do nothing } } diff --git a/core-java/src/main/java/com/baeldung/printscreen/Screenshot.java b/core-java/src/main/java/com/baeldung/printscreen/Screenshot.java new file mode 100644 index 0000000000..7f87b47476 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/printscreen/Screenshot.java @@ -0,0 +1,22 @@ +package com.baeldung.printscreen; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; + +public class Screenshot { + + private final String path; + + public Screenshot(String path) { + this.path = path; + } + + public void getScreenshot(int timeToWait) throws Exception { + Rectangle rectangle = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); + Robot robot = new Robot(); + BufferedImage img = robot.createScreenCapture(rectangle); + ImageIO.write(img, "jpg", new File(path)); + } +} diff --git a/core-java/src/main/java/com/baeldung/socket/EchoClient.java b/core-java/src/main/java/com/baeldung/socket/EchoClient.java new file mode 100644 index 0000000000..570bd60b2d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/socket/EchoClient.java @@ -0,0 +1,41 @@ +package com.baeldung.socket; + +import java.io.*; +import java.net.*; + +public class EchoClient { + private Socket clientSocket; + private PrintWriter out; + private BufferedReader in; + + public void startConnection(String ip, int port) { + try { + clientSocket = new Socket(ip, port); + out = new PrintWriter(clientSocket.getOutputStream(), true); + in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + } catch (IOException e) { + System.out.print(e); + } + + } + + public String sendMessage(String msg) { + try { + out.println(msg); + return in.readLine(); + } catch (Exception e) { + return null; + } + } + + public void stopConnection() { + try { + in.close(); + out.close(); + clientSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } +} diff --git a/core-java/src/main/java/com/baeldung/socket/EchoMultiServer.java b/core-java/src/main/java/com/baeldung/socket/EchoMultiServer.java new file mode 100644 index 0000000000..b920967545 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/socket/EchoMultiServer.java @@ -0,0 +1,70 @@ +package com.baeldung.socket; + +import java.net.*; +import java.io.*; + +public class EchoMultiServer { + private ServerSocket serverSocket; + + public void start(int port) { + try { + serverSocket = new ServerSocket(port); + while (true) + new EchoClientHandler(serverSocket.accept()).run(); + + } catch (IOException e) { + e.printStackTrace(); + } finally { + stop(); + } + + } + + public void stop() { + try { + + serverSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + private static class EchoClientHandler extends Thread { + private Socket clientSocket; + private PrintWriter out; + private BufferedReader in; + + public EchoClientHandler(Socket socket) { + this.clientSocket = socket; + } + + public void run() { + try { + out = new PrintWriter(clientSocket.getOutputStream(), true); + in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + if (".".equals(inputLine)) { + out.println("bye"); + break; + } + out.println(inputLine); + } + + in.close(); + out.close(); + clientSocket.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + EchoMultiServer server = new EchoMultiServer(); + server.start(5555); + } + +} diff --git a/core-java/src/main/java/com/baeldung/socket/EchoServer.java b/core-java/src/main/java/com/baeldung/socket/EchoServer.java new file mode 100644 index 0000000000..dfd281d51c --- /dev/null +++ b/core-java/src/main/java/com/baeldung/socket/EchoServer.java @@ -0,0 +1,49 @@ +package com.baeldung.socket; + +import java.net.*; +import java.io.*; + +public class EchoServer { + private ServerSocket serverSocket; + private Socket clientSocket; + private PrintWriter out; + private BufferedReader in; + + public void start(int port) { + try { + serverSocket = new ServerSocket(port); + clientSocket = serverSocket.accept(); + out = new PrintWriter(clientSocket.getOutputStream(), true); + in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + if (".".equals(inputLine)) { + out.println("good bye"); + break; + } + out.println(inputLine); + } + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public void stop() { + try { + in.close(); + out.close(); + clientSocket.close(); + serverSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public static void main(String[] args) { + EchoServer server = new EchoServer(); + server.start(4444); + } + +} diff --git a/core-java/src/main/java/com/baeldung/socket/GreetClient.java b/core-java/src/main/java/com/baeldung/socket/GreetClient.java new file mode 100644 index 0000000000..e6f14bb2b6 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/socket/GreetClient.java @@ -0,0 +1,44 @@ +package com.baeldung.socket; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; + +public class GreetClient { + private Socket clientSocket; + private PrintWriter out; + private BufferedReader in; + + public void startConnection(String ip, int port) { + try { + clientSocket = new Socket(ip, port); + out = new PrintWriter(clientSocket.getOutputStream(), true); + in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + } catch (IOException e) { + + } + + } + + public String sendMessage(String msg) { + try { + out.println(msg); + return in.readLine(); + } catch (Exception e) { + return null; + } + } + + public void stopConnection() { + try { + in.close(); + out.close(); + clientSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/socket/GreetServer.java b/core-java/src/main/java/com/baeldung/socket/GreetServer.java new file mode 100644 index 0000000000..05bc65a65e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/socket/GreetServer.java @@ -0,0 +1,46 @@ +package com.baeldung.socket; + +import java.net.*; +import java.io.*; + +public class GreetServer { + private ServerSocket serverSocket; + private Socket clientSocket; + private PrintWriter out; + private BufferedReader in; + + public void start(int port) { + try { + serverSocket = new ServerSocket(port); + clientSocket = serverSocket.accept(); + out = new PrintWriter(clientSocket.getOutputStream(), true); + in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + String greeting = in.readLine(); + if ("hello server".equals(greeting)) + out.println("hello client"); + else + out.println("unrecognised greeting"); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public void stop() { + try { + in.close(); + out.close(); + clientSocket.close(); + serverSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public static void main(String[] args) { + GreetServer server = new GreetServer(); + server.start(6666); + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/streamApi/Product.java b/core-java/src/main/java/com/baeldung/streamApi/Product.java similarity index 99% rename from core-java-8/src/main/java/com/baeldung/streamApi/Product.java rename to core-java/src/main/java/com/baeldung/streamApi/Product.java index 18f3a61904..26b8bd6fed 100644 --- a/core-java-8/src/main/java/com/baeldung/streamApi/Product.java +++ b/core-java/src/main/java/com/baeldung/streamApi/Product.java @@ -44,7 +44,6 @@ public class Product { this.name = name; } - public static Stream streamOf(List list) { return (list == null || list.isEmpty()) ? Stream.empty() : list.stream(); } diff --git a/core-java/src/main/java/com/baeldung/threadpool/CountingTask.java b/core-java/src/main/java/com/baeldung/threadpool/CountingTask.java new file mode 100644 index 0000000000..effdf54916 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/threadpool/CountingTask.java @@ -0,0 +1,20 @@ +package com.baeldung.threadpool; + +import java.util.concurrent.ForkJoinTask; +import java.util.concurrent.RecursiveTask; +import java.util.stream.Collectors; + +public class CountingTask extends RecursiveTask { + + private final TreeNode node; + + public CountingTask(TreeNode node) { + this.node = node; + } + + @Override + protected Integer compute() { + return node.value + node.children.stream().map(childNode -> new CountingTask(childNode).fork()).collect(Collectors.summingInt(ForkJoinTask::join)); + } + +} diff --git a/core-java/src/main/java/com/baeldung/threadpool/ExitingExecutorServiceExample.java b/core-java/src/main/java/com/baeldung/threadpool/ExitingExecutorServiceExample.java new file mode 100644 index 0000000000..4775fde930 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/threadpool/ExitingExecutorServiceExample.java @@ -0,0 +1,29 @@ +package com.baeldung.threadpool; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import com.google.common.util.concurrent.MoreExecutors; + +/** + * This class demonstrates the usage of Guava's exiting executor services that keep the VM from hanging. + * Without the exiting executor service, the task would hang indefinitely. + * This behaviour cannot be demonstrated in JUnit tests, as JUnit kills the VM after the tests. + */ +public class ExitingExecutorServiceExample { + + public static void main(String... args) { + + ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5); + ExecutorService executorService = MoreExecutors.getExitingExecutorService(executor, 100, TimeUnit.MILLISECONDS); + + executorService.submit(() -> { + while (true) { + } + }); + + } + +} diff --git a/core-java/src/main/java/com/baeldung/threadpool/TreeNode.java b/core-java/src/main/java/com/baeldung/threadpool/TreeNode.java new file mode 100644 index 0000000000..9b43152074 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/threadpool/TreeNode.java @@ -0,0 +1,18 @@ +package com.baeldung.threadpool; + +import java.util.Set; + +import com.google.common.collect.Sets; + +public class TreeNode { + + int value; + + Set children; + + public TreeNode(int value, TreeNode... children) { + this.value = value; + this.children = Sets.newHashSet(children); + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/unzip/UnzipFile.java b/core-java/src/main/java/com/baeldung/unzip/UnzipFile.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/unzip/UnzipFile.java rename to core-java/src/main/java/com/baeldung/unzip/UnzipFile.java diff --git a/core-java-8/src/main/java/com/baeldung/zip/ZipDirectory.java b/core-java/src/main/java/com/baeldung/zip/ZipDirectory.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/zip/ZipDirectory.java rename to core-java/src/main/java/com/baeldung/zip/ZipDirectory.java diff --git a/core-java-8/src/main/java/com/baeldung/zip/ZipFile.java b/core-java/src/main/java/com/baeldung/zip/ZipFile.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/zip/ZipFile.java rename to core-java/src/main/java/com/baeldung/zip/ZipFile.java diff --git a/core-java-8/src/main/java/com/baeldung/zip/ZipMultipleFiles.java b/core-java/src/main/java/com/baeldung/zip/ZipMultipleFiles.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/zip/ZipMultipleFiles.java rename to core-java/src/main/java/com/baeldung/zip/ZipMultipleFiles.java diff --git a/core-java-8/src/main/resources/dirCompressed.zip b/core-java/src/main/resources/dirCompressed.zip similarity index 100% rename from core-java-8/src/main/resources/dirCompressed.zip rename to core-java/src/main/resources/dirCompressed.zip diff --git a/core-java/src/main/resources/fileTest.txt b/core-java/src/main/resources/fileTest.txt new file mode 100644 index 0000000000..ce4bea208b --- /dev/null +++ b/core-java/src/main/resources/fileTest.txt @@ -0,0 +1 @@ +Hello World from fileTest.txt!!! \ No newline at end of file diff --git a/core-java-8/src/main/resources/multiCompressed.zip b/core-java/src/main/resources/multiCompressed.zip similarity index 100% rename from core-java-8/src/main/resources/multiCompressed.zip rename to core-java/src/main/resources/multiCompressed.zip diff --git a/core-java/src/test/java/com/baeldung/CharToStringUnitTest.java b/core-java/src/test/java/com/baeldung/CharToStringUnitTest.java new file mode 100644 index 0000000000..78742e356d --- /dev/null +++ b/core-java/src/test/java/com/baeldung/CharToStringUnitTest.java @@ -0,0 +1,53 @@ +package com.baeldung; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CharToStringUnitTest { + + @Test + public void givenChar_whenCallingStringValueOf_shouldConvertToString() { + final char givenChar = 'x'; + + final String result = String.valueOf(givenChar); + + assertThat(result).isEqualTo("x"); + } + + @Test + public void givenChar_whenCallingToStringOnCharacter_shouldConvertToString() { + final char givenChar = 'x'; + + final String result = Character.toString(givenChar); + + assertThat(result).isEqualTo("x"); + } + + @Test + public void givenChar_whenCallingCharacterConstructor_shouldConvertToString3() { + final char givenChar = 'x'; + + final String result = new Character(givenChar).toString(); + + assertThat(result).isEqualTo("x"); + } + + @Test + public void givenChar_whenConcatenated_shouldConvertToString4() { + final char givenChar = 'x'; + + final String result = givenChar + ""; + + assertThat(result).isEqualTo("x"); + } + + @Test + public void givenChar_whenFormated_shouldConvertToString5() { + final char givenChar = 'x'; + + final String result = String.format("%c", givenChar); + + assertThat(result).isEqualTo("x"); + } +} diff --git a/core-java/src/test/java/com/baeldung/RandomListElementUnitTest.java b/core-java/src/test/java/com/baeldung/RandomListElementUnitTest.java new file mode 100644 index 0000000000..6ae7c40f4d --- /dev/null +++ b/core-java/src/test/java/com/baeldung/RandomListElementUnitTest.java @@ -0,0 +1,71 @@ +package com.baeldung; + +import com.google.common.collect.Lists; +import org.junit.Test; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +public class RandomListElementUnitTest { + + @Test + public void givenList_whenRandomIndexChosen_shouldReturnARandomElementUsingRandom() { + List givenList = Lists.newArrayList(1, 2, 3); + Random rand = new Random(); + + givenList.get(rand.nextInt(givenList.size())); + } + + @Test + public void givenList_whenRandomIndexChosen_shouldReturnARandomElementUsingMathRandom() { + List givenList = Lists.newArrayList(1, 2, 3); + + givenList.get((int) (Math.random() * givenList.size())); + } + + @Test + public void givenList_whenNumberElementsChosen_shouldReturnRandomElementsRepeat() { + Random rand = new Random(); + List givenList = Lists.newArrayList("one", "two", "three", "four"); + + int numberOfElements = 2; + + for (int i = 0; i < numberOfElements; i++) { + int randomIndex = rand.nextInt(givenList.size()); + givenList.get(randomIndex); + } + } + + @Test + public void givenList_whenNumberElementsChosen_shouldReturnRandomElementsNoRepeat() { + Random rand = new Random(); + List givenList = Lists.newArrayList("one", "two", "three", "four"); + + int numberOfElements = 2; + + for (int i = 0; i < numberOfElements; i++) { + int randomIndex = rand.nextInt(givenList.size()); + givenList.get(randomIndex); + givenList.remove(randomIndex); + } + } + + @Test + public void givenList_whenSeriesLengthChosen_shouldReturnRandomSeries() { + List givenList = Lists.newArrayList(1, 2, 3, 4, 5, 6); + Collections.shuffle(givenList); + + int randomSeriesLength = 3; + + givenList.subList(0, randomSeriesLength - 1); + } + + @Test + public void givenList_whenRandomIndexChosen_shouldReturnElementThreadSafely() { + List givenList = Lists.newArrayList(1, 2, 3, 4, 5, 6); + int randomIndex = ThreadLocalRandom.current().nextInt(10) % givenList.size(); + + givenList.get(randomIndex); + } + +} diff --git a/core-java/src/test/java/com/baeldung/StringToIntOrIntegerUnitTest.java b/core-java/src/test/java/com/baeldung/StringToIntOrIntegerUnitTest.java new file mode 100644 index 0000000000..a7ad0bf114 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/StringToIntOrIntegerUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +import com.google.common.primitives.Ints; + +public class StringToIntOrIntegerUnitTest { + + @Test + public void givenString_whenParsingInt_shouldConvertToInt() { + String givenString = "42"; + + int result = Integer.parseInt(givenString); + + assertThat(result).isEqualTo(42); + } + + @Test + public void givenString_whenCallingIntegerValueOf_shouldConvertToInt() { + String givenString = "42"; + + Integer result = Integer.valueOf(givenString); + + assertThat(result).isEqualTo(new Integer(42)); + } + + @Test + public void givenString_whenCallingIntegerConstructor_shouldConvertToInt() { + String givenString = "42"; + + Integer result = new Integer(givenString); + + assertThat(result).isEqualTo(new Integer(42)); + } + + @Test + public void givenString_whenCallingIntegerDecode_shouldConvertToInt() { + String givenString = "42"; + + int result = Integer.decode(givenString); + + assertThat(result).isEqualTo(42); + } + + @Test + public void givenString_whenTryParse_shouldConvertToInt() { + String givenString = "42"; + + Integer result = Ints.tryParse(givenString); + + assertThat(result).isEqualTo(42); + } + + @Test(expected = NumberFormatException.class) + public void givenInvalidInput_whenParsingInt_shouldThrow() { + String givenString = "nan"; + Integer.parseInt(givenString); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/collectors/Java8CollectorsTest.java b/core-java/src/test/java/com/baeldung/collectors/Java8CollectorsUnitTest.java similarity index 54% rename from core-java-8/src/test/java/com/baeldung/collectors/Java8CollectorsTest.java rename to core-java/src/test/java/com/baeldung/collectors/Java8CollectorsUnitTest.java index d94f72b685..dbddbe6c54 100644 --- a/core-java-8/src/test/java/com/baeldung/collectors/Java8CollectorsTest.java +++ b/core-java/src/test/java/com/baeldung/collectors/Java8CollectorsUnitTest.java @@ -36,198 +36,143 @@ import static java.util.stream.Collectors.toSet; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -public class Java8CollectorsTest { +public class Java8CollectorsUnitTest { private final List givenList = Arrays.asList("a", "bb", "ccc", "dd"); @Test public void whenCollectingToList_shouldCollectToList() throws Exception { - final List result = givenList.stream() - .collect(toList()); + final List result = givenList.stream().collect(toList()); - assertThat(result) - .containsAll(givenList); + assertThat(result).containsAll(givenList); } @Test public void whenCollectingToList_shouldCollectToSet() throws Exception { - final Set result = givenList.stream() - .collect(toSet()); + final Set result = givenList.stream().collect(toSet()); - assertThat(result) - .containsAll(givenList); + assertThat(result).containsAll(givenList); } @Test public void whenCollectingToCollection_shouldCollectToCollection() throws Exception { - final List result = givenList.stream() - .collect(toCollection(LinkedList::new)); + final List result = givenList.stream().collect(toCollection(LinkedList::new)); - assertThat(result) - .containsAll(givenList) - .isInstanceOf(LinkedList.class); + assertThat(result).containsAll(givenList).isInstanceOf(LinkedList.class); } @Test public void whenCollectingToImmutableCollection_shouldThrowException() throws Exception { assertThatThrownBy(() -> { - givenList.stream() - .collect(toCollection(ImmutableList::of)); + givenList.stream().collect(toCollection(ImmutableList::of)); }).isInstanceOf(UnsupportedOperationException.class); } @Test public void whenCollectingToMap_shouldCollectToMap() throws Exception { - final Map result = givenList.stream() - .collect(toMap(Function.identity(), String::length)); + final Map result = givenList.stream().collect(toMap(Function.identity(), String::length)); - assertThat(result) - .containsEntry("a", 1) - .containsEntry("bb", 2) - .containsEntry("ccc", 3) - .containsEntry("dd", 2); + assertThat(result).containsEntry("a", 1).containsEntry("bb", 2).containsEntry("ccc", 3).containsEntry("dd", 2); } @Test public void whenCollectingToMap_shouldCollectToMapMerging() throws Exception { - final Map result = givenList.stream() - .collect(toMap(Function.identity(), String::length, (i1, i2) -> i1)); + final Map result = givenList.stream().collect(toMap(Function.identity(), String::length, (i1, i2) -> i1)); - assertThat(result) - .containsEntry("a", 1) - .containsEntry("bb", 2) - .containsEntry("ccc", 3) - .containsEntry("dd", 2); + assertThat(result).containsEntry("a", 1).containsEntry("bb", 2).containsEntry("ccc", 3).containsEntry("dd", 2); } @Test public void whenCollectingAndThen_shouldCollect() throws Exception { - final List result = givenList.stream() - .collect(collectingAndThen(toList(), ImmutableList::copyOf)); + final List result = givenList.stream().collect(collectingAndThen(toList(), ImmutableList::copyOf)); - assertThat(result) - .containsAll(givenList) - .isInstanceOf(ImmutableList.class); + assertThat(result).containsAll(givenList).isInstanceOf(ImmutableList.class); } @Test public void whenJoining_shouldJoin() throws Exception { - final String result = givenList.stream() - .collect(joining()); + final String result = givenList.stream().collect(joining()); - assertThat(result) - .isEqualTo("abbcccdd"); + assertThat(result).isEqualTo("abbcccdd"); } @Test public void whenJoiningWithSeparator_shouldJoinWithSeparator() throws Exception { - final String result = givenList.stream() - .collect(joining(" ")); + final String result = givenList.stream().collect(joining(" ")); - assertThat(result) - .isEqualTo("a bb ccc dd"); + assertThat(result).isEqualTo("a bb ccc dd"); } @Test public void whenJoiningWithSeparatorAndPrefixAndPostfix_shouldJoinWithSeparatorPrePost() throws Exception { - final String result = givenList.stream() - .collect(joining(" ", "PRE-", "-POST")); + final String result = givenList.stream().collect(joining(" ", "PRE-", "-POST")); - assertThat(result) - .isEqualTo("PRE-a bb ccc dd-POST"); + assertThat(result).isEqualTo("PRE-a bb ccc dd-POST"); } @Test public void whenPartitioningBy_shouldPartition() throws Exception { - final Map> result = givenList.stream() - .collect(partitioningBy(s -> s.length() > 2)); + final Map> result = givenList.stream().collect(partitioningBy(s -> s.length() > 2)); - assertThat(result) - .containsKeys(true, false) - .satisfies(booleanListMap -> { - assertThat(booleanListMap.get(true)) - .contains("ccc"); + assertThat(result).containsKeys(true, false).satisfies(booleanListMap -> { + assertThat(booleanListMap.get(true)).contains("ccc"); - assertThat(booleanListMap.get(false)) - .contains("a", "bb", "dd"); - }); + assertThat(booleanListMap.get(false)).contains("a", "bb", "dd"); + }); } @Test public void whenCounting_shouldCount() throws Exception { - final Long result = givenList.stream() - .collect(counting()); + final Long result = givenList.stream().collect(counting()); - assertThat(result) - .isEqualTo(4); + assertThat(result).isEqualTo(4); } @Test public void whenSummarizing_shouldSummarize() throws Exception { - final DoubleSummaryStatistics result = givenList.stream() - .collect(summarizingDouble(String::length)); + final DoubleSummaryStatistics result = givenList.stream().collect(summarizingDouble(String::length)); - assertThat(result.getAverage()) - .isEqualTo(2); - assertThat(result.getCount()) - .isEqualTo(4); - assertThat(result.getMax()) - .isEqualTo(3); - assertThat(result.getMin()) - .isEqualTo(1); - assertThat(result.getSum()) - .isEqualTo(8); + assertThat(result.getAverage()).isEqualTo(2); + assertThat(result.getCount()).isEqualTo(4); + assertThat(result.getMax()).isEqualTo(3); + assertThat(result.getMin()).isEqualTo(1); + assertThat(result.getSum()).isEqualTo(8); } @Test public void whenAveraging_shouldAverage() throws Exception { - final Double result = givenList.stream() - .collect(averagingDouble(String::length)); + final Double result = givenList.stream().collect(averagingDouble(String::length)); - assertThat(result) - .isEqualTo(2); + assertThat(result).isEqualTo(2); } @Test public void whenSumming_shouldSum() throws Exception { - final Double result = givenList.stream() - .collect(summingDouble(String::length)); + final Double result = givenList.stream().collect(summingDouble(String::length)); - assertThat(result) - .isEqualTo(8); + assertThat(result).isEqualTo(8); } @Test public void whenMaxingBy_shouldMaxBy() throws Exception { - final Optional result = givenList.stream() - .collect(maxBy(Comparator.naturalOrder())); + final Optional result = givenList.stream().collect(maxBy(Comparator.naturalOrder())); - assertThat(result) - .isPresent() - .hasValue("dd"); + assertThat(result).isPresent().hasValue("dd"); } @Test public void whenGroupingBy_shouldGroupBy() throws Exception { - final Map> result = givenList.stream() - .collect(groupingBy(String::length, toSet())); + final Map> result = givenList.stream().collect(groupingBy(String::length, toSet())); - assertThat(result) - .containsEntry(1, newHashSet("a")) - .containsEntry(2, newHashSet("bb", "dd")) - .containsEntry(3, newHashSet("ccc")); + assertThat(result).containsEntry(1, newHashSet("a")).containsEntry(2, newHashSet("bb", "dd")).containsEntry(3, newHashSet("ccc")); } - @Test public void whenCreatingCustomCollector_shouldCollect() throws Exception { - final ImmutableSet result = givenList.stream() - .collect(toImmutableSet()); + final ImmutableSet result = givenList.stream().collect(toImmutableSet()); - assertThat(result) - .isInstanceOf(ImmutableSet.class) - .contains("a", "bb", "ccc", "dd"); + assertThat(result).isInstanceOf(ImmutableSet.class).contains("a", "bb", "ccc", "dd"); } diff --git a/core-java/src/test/java/com/baeldung/completablefuture/CompletableFutureUnitTest.java b/core-java/src/test/java/com/baeldung/completablefuture/CompletableFutureUnitTest.java new file mode 100644 index 0000000000..df12c3d79e --- /dev/null +++ b/core-java/src/test/java/com/baeldung/completablefuture/CompletableFutureUnitTest.java @@ -0,0 +1,176 @@ +package com.baeldung.completablefuture; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.Test; + +public class CompletableFutureUnitTest { + + @Test + public void whenRunningCompletableFutureAsynchronously_thenGetMethodWaitsForResult() throws InterruptedException, ExecutionException { + Future completableFuture = calculateAsync(); + + String result = completableFuture.get(); + assertEquals("Hello", result); + } + + public Future calculateAsync() throws InterruptedException { + CompletableFuture completableFuture = new CompletableFuture<>(); + + Executors.newCachedThreadPool().submit(() -> { + Thread.sleep(500); + completableFuture.complete("Hello"); + return null; + }); + + return completableFuture; + } + + @Test + public void whenRunningCompletableFutureWithResult_thenGetMethodReturnsImmediately() throws InterruptedException, ExecutionException { + Future completableFuture = CompletableFuture.completedFuture("Hello"); + + String result = completableFuture.get(); + assertEquals("Hello", result); + } + + public Future calculateAsyncWithCancellation() throws InterruptedException { + CompletableFuture completableFuture = new CompletableFuture<>(); + + Executors.newCachedThreadPool().submit(() -> { + Thread.sleep(500); + completableFuture.cancel(false); + return null; + }); + + return completableFuture; + } + + @Test(expected = CancellationException.class) + public void whenCancelingTheFuture_thenThrowsCancellationException() throws ExecutionException, InterruptedException { + Future future = calculateAsyncWithCancellation(); + future.get(); + } + + @Test + public void whenCreatingCompletableFutureWithSupplyAsync_thenFutureReturnsValue() throws ExecutionException, InterruptedException { + CompletableFuture future = CompletableFuture.supplyAsync(() -> "Hello"); + + assertEquals("Hello", future.get()); + } + + @Test + public void whenAddingThenAcceptToFuture_thenFunctionExecutesAfterComputationIsFinished() throws ExecutionException, InterruptedException { + CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> "Hello"); + + CompletableFuture future = completableFuture.thenAccept(s -> System.out.println("Computation returned: " + s)); + + future.get(); + } + + @Test + public void whenAddingThenRunToFuture_thenFunctionExecutesAfterComputationIsFinished() throws ExecutionException, InterruptedException { + CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> "Hello"); + + CompletableFuture future = completableFuture.thenRun(() -> System.out.println("Computation finished.")); + + future.get(); + } + + @Test + public void whenAddingThenApplyToFuture_thenFunctionExecutesAfterComputationIsFinished() throws ExecutionException, InterruptedException { + CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> "Hello"); + + CompletableFuture future = completableFuture.thenApply(s -> s + " World"); + + assertEquals("Hello World", future.get()); + } + + @Test + public void whenUsingThenCompose_thenFuturesExecuteSequentially() throws ExecutionException, InterruptedException { + CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> "Hello").thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " World")); + + assertEquals("Hello World", completableFuture.get()); + } + + @Test + public void whenUsingThenCombine_thenWaitForExecutionOfBothFutures() throws ExecutionException, InterruptedException { + CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> "Hello").thenCombine(CompletableFuture.supplyAsync(() -> " World"), (s1, s2) -> s1 + s2); + + assertEquals("Hello World", completableFuture.get()); + } + + @Test + public void whenUsingThenAcceptBoth_thenWaitForExecutionOfBothFutures() throws ExecutionException, InterruptedException { + CompletableFuture.supplyAsync(() -> "Hello").thenAcceptBoth(CompletableFuture.supplyAsync(() -> " World"), (s1, s2) -> System.out.println(s1 + s2)); + } + + @Test + public void whenFutureCombinedWithAllOfCompletes_thenAllFuturesAreDone() throws ExecutionException, InterruptedException { + CompletableFuture future1 = CompletableFuture.supplyAsync(() -> "Hello"); + CompletableFuture future2 = CompletableFuture.supplyAsync(() -> "Beautiful"); + CompletableFuture future3 = CompletableFuture.supplyAsync(() -> "World"); + + CompletableFuture combinedFuture = CompletableFuture.allOf(future1, future2, future3); + + // ... + + combinedFuture.get(); + + assertTrue(future1.isDone()); + assertTrue(future2.isDone()); + assertTrue(future3.isDone()); + + String combined = Stream.of(future1, future2, future3).map(CompletableFuture::join).collect(Collectors.joining(" ")); + + assertEquals("Hello Beautiful World", combined); + } + + @Test + public void whenFutureThrows_thenHandleMethodReceivesException() throws ExecutionException, InterruptedException { + String name = null; + + // ... + + CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> { + if (name == null) { + throw new RuntimeException("Computation error!"); + } + return "Hello, " + name; + }).handle((s, t) -> s != null ? s : "Hello, Stranger!"); + + assertEquals("Hello, Stranger!", completableFuture.get()); + } + + @Test(expected = ExecutionException.class) + public void whenCompletingFutureExceptionally_thenGetMethodThrows() throws ExecutionException, InterruptedException { + CompletableFuture completableFuture = new CompletableFuture<>(); + + // ... + + completableFuture.completeExceptionally(new RuntimeException("Calculation failed!")); + + // ... + + completableFuture.get(); + } + + @Test + public void whenAddingThenApplyAsyncToFuture_thenFunctionExecutesAfterComputationIsFinished() throws ExecutionException, InterruptedException { + CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> "Hello"); + + CompletableFuture future = completableFuture.thenApplyAsync(s -> s + " World"); + + assertEquals("Hello World", future.get()); + } + +} \ No newline at end of file diff --git a/core-java-8/src/test/java/com/baeldung/dateapi/ConversionExample.java b/core-java/src/test/java/com/baeldung/dateapi/ConversionExample.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/dateapi/ConversionExample.java rename to core-java/src/test/java/com/baeldung/dateapi/ConversionExample.java diff --git a/core-java-8/src/test/java/com/baeldung/dateapi/JavaUtilTimeTest.java b/core-java/src/test/java/com/baeldung/dateapi/JavaUtilTimeUnitTest.java similarity index 98% rename from core-java-8/src/test/java/com/baeldung/dateapi/JavaUtilTimeTest.java rename to core-java/src/test/java/com/baeldung/dateapi/JavaUtilTimeUnitTest.java index 4bce40c2d9..e4753dbd5c 100644 --- a/core-java-8/src/test/java/com/baeldung/dateapi/JavaUtilTimeTest.java +++ b/core-java/src/test/java/com/baeldung/dateapi/JavaUtilTimeUnitTest.java @@ -14,7 +14,7 @@ import java.time.temporal.ChronoUnit; import static org.assertj.core.api.Assertions.assertThat; -public class JavaUtilTimeTest { +public class JavaUtilTimeUnitTest { @Test public void currentTime() { diff --git a/core-java/src/test/java/com/baeldung/datetime/UseLocalDateTimeUnitTest.java b/core-java/src/test/java/com/baeldung/datetime/UseLocalDateTimeUnitTest.java new file mode 100644 index 0000000000..57e1f33280 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/datetime/UseLocalDateTimeUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.datetime; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.Month; + +import org.junit.Assert; +import org.junit.Test; + +public class UseLocalDateTimeUnitTest { + + UseLocalDateTime useLocalDateTime = new UseLocalDateTime(); + + @Test + public void givenString_whenUsingParse_thenLocalDateTime() { + Assert.assertEquals(LocalDate.of(2016, Month.MAY, 10), useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30").toLocalDate()); + Assert.assertEquals(LocalTime.of(6, 30), useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30").toLocalTime()); + } +} diff --git a/core-java/src/test/java/com/baeldung/datetime/UseLocalDateUnitTest.java b/core-java/src/test/java/com/baeldung/datetime/UseLocalDateUnitTest.java new file mode 100644 index 0000000000..8f1997e9e8 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/datetime/UseLocalDateUnitTest.java @@ -0,0 +1,54 @@ +package com.baeldung.datetime; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.LocalDateTime; + +import org.junit.Assert; +import org.junit.Test; + +public class UseLocalDateUnitTest { + + UseLocalDate useLocalDate = new UseLocalDate(); + + @Test + public void givenValues_whenUsingFactoryOf_thenLocalDate() { + Assert.assertEquals("2016-05-10", useLocalDate.getLocalDateUsingFactoryOfMethod(2016, 5, 10).toString()); + } + + @Test + public void givenString_whenUsingParse_thenLocalDate() { + Assert.assertEquals("2016-05-10", useLocalDate.getLocalDateUsingParseMethod("2016-05-10").toString()); + } + + @Test + public void whenUsingClock_thenLocalDate() { + Assert.assertEquals(LocalDate.now(), useLocalDate.getLocalDateFromClock()); + } + + @Test + public void givenDate_whenUsingPlus_thenNextDay() { + Assert.assertEquals(LocalDate.now().plusDays(1), useLocalDate.getNextDay(LocalDate.now())); + } + + @Test + public void givenDate_whenUsingMinus_thenPreviousDay() { + Assert.assertEquals(LocalDate.now().minusDays(1), useLocalDate.getPreviousDay(LocalDate.now())); + } + + @Test + public void givenToday_whenUsingGetDayOfWeek_thenDayOfWeek() { + Assert.assertEquals(DayOfWeek.SUNDAY, useLocalDate.getDayOfWeek(LocalDate.parse("2016-05-22"))); + } + + @Test + public void givenToday_whenUsingWithTemporalAdjuster_thenFirstDayOfMonth() { + Assert.assertEquals(1, useLocalDate.getFirstDayOfMonth().getDayOfMonth()); + } + + @Test + public void givenLocalDate_whenUsingAtStartOfDay_thenReturnMidnight() { + Assert.assertEquals(LocalDateTime.parse("2016-05-22T00:00:00"), useLocalDate.getStartOfDay(LocalDate.parse("2016-05-22"))); + } + +} diff --git a/core-java/src/test/java/com/baeldung/datetime/UseLocalTimeUnitTest.java b/core-java/src/test/java/com/baeldung/datetime/UseLocalTimeUnitTest.java new file mode 100644 index 0000000000..996e200ae9 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/datetime/UseLocalTimeUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.datetime; + +import java.time.LocalTime; + +import org.junit.Assert; +import org.junit.Test; + +public class UseLocalTimeUnitTest { + + UseLocalTime useLocalTime = new UseLocalTime(); + + @Test + public void givenValues_whenUsingFactoryOf_thenLocalTime() { + Assert.assertEquals("07:07:07", useLocalTime.getLocalTimeUsingFactoryOfMethod(7, 7, 7).toString()); + } + + @Test + public void givenString_whenUsingParse_thenLocalTime() { + Assert.assertEquals("06:30", useLocalTime.getLocalTimeUsingParseMethod("06:30").toString()); + } + + @Test + public void givenTime_whenAddHour_thenLocalTime() { + Assert.assertEquals("07:30", useLocalTime.addAnHour(LocalTime.of(6, 30)).toString()); + } + + @Test + public void getHourFromLocalTime() { + Assert.assertEquals(1, useLocalTime.getHourFromLocalTime(LocalTime.of(1, 1))); + } + + @Test + public void getLocalTimeWithMinuteSetToValue() { + Assert.assertEquals(LocalTime.of(10, 20), useLocalTime.getLocalTimeWithMinuteSetToValue(LocalTime.of(10, 10), 20)); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UsePeriodTest.java b/core-java/src/test/java/com/baeldung/datetime/UsePeriodUnitTest.java similarity index 63% rename from core-java-8/src/test/java/com/baeldung/datetime/UsePeriodTest.java rename to core-java/src/test/java/com/baeldung/datetime/UsePeriodUnitTest.java index 8a3228aaa5..7c030c328a 100644 --- a/core-java-8/src/test/java/com/baeldung/datetime/UsePeriodTest.java +++ b/core-java/src/test/java/com/baeldung/datetime/UsePeriodUnitTest.java @@ -1,29 +1,26 @@ package com.baeldung.datetime; import java.time.LocalDate; -import java.time.LocalDateTime; import java.time.Period; -import java.time.ZoneId; -import java.time.ZonedDateTime; import org.junit.Assert; import org.junit.Test; -public class UsePeriodTest { - UsePeriod usingPeriod=new UsePeriod(); - +public class UsePeriodUnitTest { + UsePeriod usingPeriod = new UsePeriod(); + @Test - public void givenPeriodAndLocalDate_thenCalculateModifiedDate(){ + public void givenPeriodAndLocalDate_thenCalculateModifiedDate() { Period period = Period.ofDays(1); LocalDate localDate = LocalDate.parse("2007-05-10"); - Assert.assertEquals(localDate.plusDays(1),usingPeriod.modifyDates(localDate, period)); + Assert.assertEquals(localDate.plusDays(1), usingPeriod.modifyDates(localDate, period)); } - + @Test - public void givenDates_thenGetPeriod(){ + public void givenDates_thenGetPeriod() { LocalDate localDate1 = LocalDate.parse("2007-05-10"); LocalDate localDate2 = LocalDate.parse("2007-05-15"); - + Assert.assertEquals(Period.ofDays(5), usingPeriod.getDifferenceBetweenDates(localDate1, localDate2)); } } diff --git a/core-java/src/test/java/com/baeldung/datetime/UseZonedDateTimeUnitTest.java b/core-java/src/test/java/com/baeldung/datetime/UseZonedDateTimeUnitTest.java new file mode 100644 index 0000000000..5fb079b94c --- /dev/null +++ b/core-java/src/test/java/com/baeldung/datetime/UseZonedDateTimeUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.datetime; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import org.junit.Assert; +import org.junit.Test; + +public class UseZonedDateTimeUnitTest { + + UseZonedDateTime zonedDateTime = new UseZonedDateTime(); + + @Test + public void givenZoneId_thenZonedDateTime() { + ZoneId zoneId = ZoneId.of("Europe/Paris"); + ZonedDateTime zonedDatetime = zonedDateTime.getZonedDateTime(LocalDateTime.parse("2016-05-20T06:30"), zoneId); + Assert.assertEquals(zoneId, ZoneId.from(zonedDatetime)); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/doublecolon/TestComputerUtils.java b/core-java/src/test/java/com/baeldung/doublecolon/ComputerUtilsUnitTest.java similarity index 98% rename from core-java-8/src/test/java/com/baeldung/doublecolon/TestComputerUtils.java rename to core-java/src/test/java/com/baeldung/doublecolon/ComputerUtilsUnitTest.java index 85194f5aa6..f69e4b03ee 100644 --- a/core-java-8/src/test/java/com/baeldung/doublecolon/TestComputerUtils.java +++ b/core-java/src/test/java/com/baeldung/doublecolon/ComputerUtilsUnitTest.java @@ -13,7 +13,7 @@ import java.util.function.BiFunction; import static com.baeldung.doublecolon.ComputerUtils.*; -public class TestComputerUtils { +public class ComputerUtilsUnitTest { @Before public void setup() { diff --git a/core-java/src/test/java/com/baeldung/encoderdecoder/EncoderDecoderUnitTest.java b/core-java/src/test/java/com/baeldung/encoderdecoder/EncoderDecoderUnitTest.java new file mode 100644 index 0000000000..c944dfa6fe --- /dev/null +++ b/core-java/src/test/java/com/baeldung/encoderdecoder/EncoderDecoderUnitTest.java @@ -0,0 +1,77 @@ +package com.baeldung.encoderdecoder; + +import org.hamcrest.CoreMatchers; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import static java.util.stream.Collectors.joining; + +public class EncoderDecoderUnitTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(EncoderDecoderUnitTest.class); + private static final String testUrl = "http://www.baeldung.com?key1=value+1&key2=value%40%21%242&key3=value%253"; + + private String encodeValue(String value) { + String encoded = null; + try { + encoded = URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); + } catch (UnsupportedEncodingException e) { + LOGGER.error("Error encoding parameter {}", e.getMessage(), e); + } + return encoded; + } + + private String decode(String value) { + String decoded = null; + try { + decoded = URLDecoder.decode(value, StandardCharsets.UTF_8.toString()); + } catch (UnsupportedEncodingException e) { + LOGGER.error("Error encoding parameter {}", e.getMessage(), e); + } + return decoded; + } + + @Test + public void givenURL_whenAnalyze_thenCorrect() throws Exception { + URL url = new URL(testUrl); + + Assert.assertThat(url.getProtocol(), CoreMatchers.is("http")); + Assert.assertThat(url.getHost(), CoreMatchers.is("www.baeldung.com")); + Assert.assertThat(url.getQuery(), CoreMatchers.is("key1=value+1&key2=value%40%21%242&key3=value%253")); + } + + @Test + public void givenRequestParam_whenUTF8Scheme_thenEncode() throws Exception { + Map requestParams = new HashMap<>(); + requestParams.put("key1", "value 1"); + requestParams.put("key2", "value@!$2"); + requestParams.put("key3", "value%3"); + + String encodedURL = requestParams.keySet().stream().map(key -> key + "=" + encodeValue(requestParams.get(key))).collect(joining("&", "http://www.baeldung.com?", "")); + + Assert.assertThat(testUrl, CoreMatchers.is(encodedURL)); + } + + @Test + public void givenRequestParam_whenUTF8Scheme_thenDecodeRequestParams() throws Exception { + URL url = new URL(testUrl); + + String query = url.getQuery(); + + String decodedQuery = Arrays.stream(query.split("&")).map(param -> param.split("=")[0] + "=" + decode(param.split("=")[1])).collect(joining("&")); + + Assert.assertEquals("http://www.baeldung.com?key1=value 1&key2=value@!$2&key3=value%3", url.getProtocol() + "://" + url.getHost() + "?" + decodedQuery); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/enums/PizzaTest.java b/core-java/src/test/java/com/baeldung/enums/PizzaUnitTest.java similarity index 98% rename from core-java-8/src/test/java/com/baeldung/enums/PizzaTest.java rename to core-java/src/test/java/com/baeldung/enums/PizzaUnitTest.java index deeebaa240..6cf6ad3551 100644 --- a/core-java-8/src/test/java/com/baeldung/enums/PizzaTest.java +++ b/core-java/src/test/java/com/baeldung/enums/PizzaUnitTest.java @@ -1,6 +1,5 @@ package com.baeldung.enums; - import org.junit.Test; import java.util.ArrayList; @@ -9,7 +8,7 @@ import java.util.List; import static junit.framework.TestCase.assertTrue; -public class PizzaTest { +public class PizzaUnitTest { @Test public void givenPizaOrder_whenReady_thenDeliverable() { diff --git a/core-java/src/test/java/com/baeldung/file/FileOperationsUnitTest.java b/core-java/src/test/java/com/baeldung/file/FileOperationsUnitTest.java new file mode 100644 index 0000000000..3319716dc6 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/file/FileOperationsUnitTest.java @@ -0,0 +1,121 @@ +package com.baeldung.file; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Stream; + +import org.apache.commons.io.FileUtils; +import org.hamcrest.CoreMatchers; +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Test; + +public class FileOperationsUnitTest { + + @Test + public void givenFileName_whenUsingClassloader_thenFileData() throws IOException { + String expectedData = "Hello World from fileTest.txt!!!"; + + ClassLoader classLoader = getClass().getClassLoader(); + File file = new File(classLoader.getResource("fileTest.txt").getFile()); + InputStream inputStream = new FileInputStream(file); + String data = readFromInputStream(inputStream); + + Assert.assertEquals(expectedData, data.trim()); + } + + @Test + public void givenFileNameAsAbsolutePath_whenUsingClasspath_thenFileData() throws IOException { + String expectedData = "Hello World from fileTest.txt!!!"; + + Class clazz = FileOperationsUnitTest.class; + InputStream inputStream = clazz.getResourceAsStream("/fileTest.txt"); + String data = readFromInputStream(inputStream); + + Assert.assertEquals(expectedData, data.trim()); + } + + @Test + public void givenFileName_whenUsingJarFile_thenFileData() throws IOException { + String expectedData = "BSD License"; + + Class clazz = Matchers.class; + InputStream inputStream = clazz.getResourceAsStream("/LICENSE.txt"); + String data = readFromInputStream(inputStream); + + Assert.assertThat(data.trim(), CoreMatchers.containsString(expectedData)); + } + + @Test + public void givenURLName_whenUsingURL_thenFileData() throws IOException { + String expectedData = "Baeldung"; + + URL urlObject = new URL("http://www.baeldung.com/"); + + URLConnection urlConnection = urlObject.openConnection(); + + InputStream inputStream = urlConnection.getInputStream(); + String data = readFromInputStream(inputStream); + + Assert.assertThat(data.trim(), CoreMatchers.containsString(expectedData)); + } + + @Test + public void givenFileName_whenUsingFileUtils_thenFileData() throws IOException { + String expectedData = "Hello World from fileTest.txt!!!"; + + ClassLoader classLoader = getClass().getClassLoader(); + File file = new File(classLoader.getResource("fileTest.txt").getFile()); + String data = FileUtils.readFileToString(file); + + Assert.assertEquals(expectedData, data.trim()); + } + + @Test + public void givenFilePath_whenUsingFilesReadAllBytes_thenFileData() throws IOException, URISyntaxException { + String expectedData = "Hello World from fileTest.txt!!!"; + + Path path = Paths.get(getClass().getClassLoader().getResource("fileTest.txt").toURI()); + + byte[] fileBytes = Files.readAllBytes(path); + String data = new String(fileBytes); + + Assert.assertEquals(expectedData, data.trim()); + } + + @Test + public void givenFilePath_whenUsingFilesLines_thenFileData() throws IOException, URISyntaxException { + String expectedData = "Hello World from fileTest.txt!!!"; + + Path path = Paths.get(getClass().getClassLoader().getResource("fileTest.txt").toURI()); + + StringBuilder data = new StringBuilder(); + Stream lines = Files.lines(path); + lines.forEach(line -> data.append(line).append("\n")); + lines.close(); + + Assert.assertEquals(expectedData, data.toString().trim()); + } + + private String readFromInputStream(InputStream inputStream) throws IOException { + StringBuilder resultStringBuilder = new StringBuilder(); + try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + resultStringBuilder.append(line).append("\n"); + } + } + + return resultStringBuilder.toString(); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/functionalinterface/FunctionalInterfaceUnitTest.java b/core-java/src/test/java/com/baeldung/functionalinterface/FunctionalInterfaceUnitTest.java new file mode 100644 index 0000000000..6f3384c8eb --- /dev/null +++ b/core-java/src/test/java/com/baeldung/functionalinterface/FunctionalInterfaceUnitTest.java @@ -0,0 +1,182 @@ +package com.baeldung.functionalinterface; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.Test; + +import com.google.common.util.concurrent.Uninterruptibles; + +public class FunctionalInterfaceUnitTest { + + @Test + public void whenPassingLambdaToComputeIfAbsent_thenTheValueGetsComputedAndPutIntoMap() { + Map nameMap = new HashMap<>(); + Integer value = nameMap.computeIfAbsent("John", s -> s.length()); + + assertEquals(new Integer(4), nameMap.get("John")); + assertEquals(new Integer(4), value); + } + + @Test + public void whenPassingMethodReferenceToComputeIfAbsent_thenTheValueGetsComputedAndPutIntoMap() { + Map nameMap = new HashMap<>(); + Integer value = nameMap.computeIfAbsent("John", String::length); + + assertEquals(new Integer(4), nameMap.get("John")); + assertEquals(new Integer(4), value); + } + + @Test + public void whenUsingCustomFunctionalInterfaceForPrimitives_thenCanUseItAsLambda() { + + short[] array = { (short) 1, (short) 2, (short) 3 }; + byte[] transformedArray = transformArray(array, s -> (byte) (s * 2)); + + byte[] expectedArray = { (byte) 2, (byte) 4, (byte) 6 }; + assertArrayEquals(expectedArray, transformedArray); + + } + + @Test + public void whenUsingBiFunction_thenCanUseItToReplaceMapValues() { + Map salaries = new HashMap<>(); + salaries.put("John", 40000); + salaries.put("Freddy", 30000); + salaries.put("Samuel", 50000); + + salaries.replaceAll((name, oldValue) -> name.equals("Freddy") ? oldValue : oldValue + 10000); + + assertEquals(new Integer(50000), salaries.get("John")); + assertEquals(new Integer(30000), salaries.get("Freddy")); + assertEquals(new Integer(60000), salaries.get("Samuel")); + } + + @Test + public void whenPassingLambdaToThreadConstructor_thenLambdaInferredToRunnable() { + Thread thread = new Thread(() -> System.out.println("Hello From Another Thread")); + thread.start(); + } + + @Test + public void whenUsingSupplierToGenerateNumbers_thenCanUseItInStreamGenerate() { + + int[] fibs = { 0, 1 }; + Stream fibonacci = Stream.generate(() -> { + int result = fibs[1]; + int fib3 = fibs[0] + fibs[1]; + fibs[0] = fibs[1]; + fibs[1] = fib3; + return result; + }); + + List fibonacci5 = fibonacci.limit(5).collect(Collectors.toList()); + + assertEquals(new Integer(1), fibonacci5.get(0)); + assertEquals(new Integer(1), fibonacci5.get(1)); + assertEquals(new Integer(2), fibonacci5.get(2)); + assertEquals(new Integer(3), fibonacci5.get(3)); + assertEquals(new Integer(5), fibonacci5.get(4)); + } + + @Test + public void whenUsingConsumerInForEach_thenConsumerExecutesForEachListElement() { + List names = Arrays.asList("John", "Freddy", "Samuel"); + names.forEach(name -> System.out.println("Hello, " + name)); + } + + @Test + public void whenUsingBiConsumerInForEach_thenConsumerExecutesForEachMapElement() { + Map ages = new HashMap<>(); + ages.put("John", 25); + ages.put("Freddy", 24); + ages.put("Samuel", 30); + + ages.forEach((name, age) -> System.out.println(name + " is " + age + " years old")); + } + + @Test + public void whenUsingPredicateInFilter_thenListValuesAreFilteredOut() { + List names = Arrays.asList("Angela", "Aaron", "Bob", "Claire", "David"); + + List namesWithA = names.stream().filter(name -> name.startsWith("A")).collect(Collectors.toList()); + + assertEquals(2, namesWithA.size()); + assertTrue(namesWithA.contains("Angela")); + assertTrue(namesWithA.contains("Aaron")); + } + + @Test + public void whenUsingUnaryOperatorWithReplaceAll_thenAllValuesInTheListAreReplaced() { + List names = Arrays.asList("bob", "josh", "megan"); + + names.replaceAll(String::toUpperCase); + + assertEquals("BOB", names.get(0)); + assertEquals("JOSH", names.get(1)); + assertEquals("MEGAN", names.get(2)); + } + + @Test + public void whenUsingBinaryOperatorWithStreamReduce_thenResultIsSumOfValues() { + + List values = Arrays.asList(3, 5, 8, 9, 12); + + int sum = values.stream().reduce(0, (i1, i2) -> i1 + i2); + + assertEquals(37, sum); + + } + + @Test + public void whenComposingTwoFunctions_thenFunctionsExecuteSequentially() { + + Function intToString = Object::toString; + Function quote = s -> "'" + s + "'"; + + Function quoteIntToString = quote.compose(intToString); + + assertEquals("'5'", quoteIntToString.apply(5)); + + } + + @Test + public void whenUsingSupplierToGenerateValue_thenValueIsGeneratedLazily() { + + Supplier lazyValue = () -> { + Uninterruptibles.sleepUninterruptibly(1000, TimeUnit.MILLISECONDS); + return 9d; + }; + + double valueSquared = squareLazy(lazyValue); + + assertEquals(81d, valueSquared, 0); + + } + + // + + public double squareLazy(Supplier lazyValue) { + return Math.pow(lazyValue.get(), 2); + } + + public byte[] transformArray(short[] array, ShortToByteFunction function) { + byte[] transformedArray = new byte[array.length]; + for (int i = 0; i < array.length; i++) { + transformedArray[i] = function.applyAsByte(array[i]); + } + return transformedArray; + } + +} diff --git a/core-java/src/test/java/com/baeldung/functionalinterface/ShortToByteFunction.java b/core-java/src/test/java/com/baeldung/functionalinterface/ShortToByteFunction.java new file mode 100644 index 0000000000..3231d6244f --- /dev/null +++ b/core-java/src/test/java/com/baeldung/functionalinterface/ShortToByteFunction.java @@ -0,0 +1,8 @@ +package com.baeldung.functionalinterface; + +@FunctionalInterface +public interface ShortToByteFunction { + + byte applyAsByte(short s); + +} diff --git a/core-java/src/test/java/com/baeldung/hexToAscii/HexToAscii.java b/core-java/src/test/java/com/baeldung/hexToAscii/HexToAscii.java new file mode 100644 index 0000000000..2a3c4b109e --- /dev/null +++ b/core-java/src/test/java/com/baeldung/hexToAscii/HexToAscii.java @@ -0,0 +1,46 @@ +package com.baeldung.hexToAscii; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class HexToAscii { + + @Test + public static void whenHexToAscii() { + String asciiString = "http://www.baeldung.com/jackson-serialize-dates"; + String hexEquivalent = "687474703a2f2f7777772e6261656c64756e672e636f6d2f6a61636b736f6e2d73657269616c697a652d6461746573"; + + assertEquals(asciiString, hexToAscii(hexEquivalent)); + } + + @Test + public static void whenAsciiToHex() { + String asciiString = "http://www.baeldung.com/jackson-serialize-dates"; + String hexEquivalent = "687474703a2f2f7777772e6261656c64756e672e636f6d2f6a61636b736f6e2d73657269616c697a652d6461746573"; + + assertEquals(hexEquivalent, asciiToHex(asciiString)); + } + + // + + private static String asciiToHex(String asciiStr) { + char[] chars = asciiStr.toCharArray(); + StringBuilder hex = new StringBuilder(); + for (char ch : chars) { + hex.append(Integer.toHexString((int) ch)); + } + + return hex.toString(); + } + + private static String hexToAscii(String hexStr) { + StringBuilder output = new StringBuilder(""); + for (int i = 0; i < hexStr.length(); i += 2) { + String str = hexStr.substring(i, i + 2); + output.append((char) Integer.parseInt(str, 16)); + } + return output.toString(); + } + +} diff --git a/core-java/src/test/java/com/baeldung/java/networking/interfaces/NetworkInterfaceManualTest.java b/core-java/src/test/java/com/baeldung/java/networking/interfaces/NetworkInterfaceManualTest.java new file mode 100644 index 0000000000..8635a24f18 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/networking/interfaces/NetworkInterfaceManualTest.java @@ -0,0 +1,118 @@ +package com.baeldung.java.networking.interfaces; + +import org.junit.Test; + +import java.net.*; +import java.util.Enumeration; +import java.util.List; + +import static org.junit.Assert.*; + +public class NetworkInterfaceManualTest { + @Test + public void givenName_whenReturnsNetworkInterface_thenCorrect() throws SocketException { + NetworkInterface nif = NetworkInterface.getByName("lo"); + assertNotNull(nif); + } + + @Test + public void givenInExistentName_whenReturnsNull_thenCorrect() throws SocketException { + NetworkInterface nif = NetworkInterface.getByName("inexistent_name"); + assertNull(nif); + } + + @Test + public void givenIP_whenReturnsNetworkInterface_thenCorrect() throws SocketException, UnknownHostException { + byte[] ip = new byte[] { 127, 0, 0, 1 }; + NetworkInterface nif = NetworkInterface.getByInetAddress(InetAddress.getByAddress(ip)); + assertNotNull(nif); + } + + @Test + public void givenHostName_whenReturnsNetworkInterface_thenCorrect() throws SocketException, UnknownHostException { + NetworkInterface nif = NetworkInterface.getByInetAddress(InetAddress.getByName("localhost")); + assertNotNull(nif); + } + + @Test + public void givenLocalHost_whenReturnsNetworkInterface_thenCorrect() throws SocketException, UnknownHostException { + NetworkInterface nif = NetworkInterface.getByInetAddress(InetAddress.getLocalHost()); + assertNotNull(nif); + } + + @Test + public void givenLoopBack_whenReturnsNetworkInterface_thenCorrect() throws SocketException, UnknownHostException { + NetworkInterface nif = NetworkInterface.getByInetAddress(InetAddress.getLoopbackAddress()); + assertNotNull(nif); + } + + @Test + public void givenIndex_whenReturnsNetworkInterface_thenCorrect() throws SocketException, UnknownHostException { + NetworkInterface nif = NetworkInterface.getByIndex(0); + assertNotNull(nif); + } + + @Test + public void givenInterface_whenReturnsInetAddresses_thenCorrect() throws SocketException, UnknownHostException { + NetworkInterface nif = NetworkInterface.getByName("lo"); + Enumeration addressEnum = nif.getInetAddresses(); + InetAddress address = addressEnum.nextElement(); + assertEquals("127.0.0.1", address.getHostAddress()); + } + + @Test + public void givenInterface_whenReturnsInterfaceAddresses_thenCorrect() throws SocketException, UnknownHostException { + NetworkInterface nif = NetworkInterface.getByName("lo"); + + List addressEnum = nif.getInterfaceAddresses(); + InterfaceAddress address = addressEnum.get(0); + InetAddress localAddress = address.getAddress(); + InetAddress broadCastAddress = address.getBroadcast(); + assertEquals("127.0.0.1", localAddress.getHostAddress()); + assertEquals("127.255.255.255", broadCastAddress.getHostAddress()); + } + + @Test + public void givenInterface_whenChecksIfLoopback_thenCorrect() throws SocketException, UnknownHostException { + NetworkInterface nif = NetworkInterface.getByName("lo"); + assertTrue(nif.isLoopback()); + } + + @Test + public void givenInterface_whenChecksIfUp_thenCorrect() throws SocketException, UnknownHostException { + NetworkInterface nif = NetworkInterface.getByName("lo"); + assertTrue(nif.isUp()); + } + + @Test + public void givenInterface_whenChecksIfPointToPoint_thenCorrect() throws SocketException, UnknownHostException { + NetworkInterface nif = NetworkInterface.getByName("lo"); + assertFalse(nif.isPointToPoint()); + } + + @Test + public void givenInterface_whenChecksIfVirtual_thenCorrect() throws SocketException, UnknownHostException { + NetworkInterface nif = NetworkInterface.getByName("lo"); + assertFalse(nif.isVirtual()); + } + + @Test + public void givenInterface_whenChecksMulticastSupport_thenCorrect() throws SocketException, UnknownHostException { + NetworkInterface nif = NetworkInterface.getByName("lo"); + assertTrue(nif.supportsMulticast()); + } + + @Test + public void givenInterface_whenGetsMacAddress_thenCorrect() throws SocketException, UnknownHostException { + NetworkInterface nif = NetworkInterface.getByName("lo"); + byte[] bytes = nif.getHardwareAddress(); + assertNotNull(bytes); + } + + @Test + public void givenInterface_whenGetsMTU_thenCorrect() throws SocketException, UnknownHostException { + NetworkInterface nif = NetworkInterface.getByName("net0"); + int mtu = nif.getMTU(); + assertEquals(1500, mtu); + } +} diff --git a/core-java/src/test/java/com/baeldung/java/networking/udp/UDPIntegrationTest.java b/core-java/src/test/java/com/baeldung/java/networking/udp/UDPIntegrationTest.java new file mode 100644 index 0000000000..aff851ae4b --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/networking/udp/UDPIntegrationTest.java @@ -0,0 +1,38 @@ +package com.baeldung.java.networking.udp; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +public class UDPIntegrationTest { + private EchoClient client; + + @Before + public void setup() throws IOException { + new EchoServer().start(); + client = new EchoClient(); + } + + @Test + public void whenCanSendAndReceivePacket_thenCorrect1() { + String echo = client.sendEcho("hello server"); + assertEquals("hello server", echo); + echo = client.sendEcho("server is working"); + assertFalse(echo.equals("hello server")); + } + + @After + public void tearDown() { + stopEchoServer(); + client.close(); + } + + private void stopEchoServer() { + client.sendEcho("end"); + } +} diff --git a/core-java/src/test/java/com/baeldung/java/networking/url/UrlUnitTest.java b/core-java/src/test/java/com/baeldung/java/networking/url/UrlUnitTest.java new file mode 100644 index 0000000000..505d9595ab --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/networking/url/UrlUnitTest.java @@ -0,0 +1,104 @@ +package com.baeldung.java.networking.url; + +import static org.junit.Assert.assertEquals; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.junit.Test; + +public class UrlUnitTest { + + @Test + public void givenUrl_whenCanIdentifyProtocol_thenCorrect() throws MalformedURLException { + final URL url = new URL("http://baeldung.com"); + assertEquals("http", url.getProtocol()); + } + + @Test + public void givenUrl_whenCanGetHost_thenCorrect() throws MalformedURLException { + final URL url = new URL("http://baeldung.com"); + assertEquals("baeldung.com", url.getHost()); + } + + @Test + public void givenUrl_whenCanGetFileName_thenCorrect2() throws MalformedURLException { + final URL url = new URL("http://baeldung.com/articles?topic=java&version=8"); + assertEquals("/articles?topic=java&version=8", url.getFile()); + } + + @Test + public void givenUrl_whenCanGetFileName_thenCorrect1() throws MalformedURLException { + final URL url = new URL("http://baeldung.com/guidelines.txt"); + assertEquals("/guidelines.txt", url.getFile()); + } + + @Test + public void givenUrl_whenCanGetPathParams_thenCorrect() throws MalformedURLException { + final URL url = new URL("http://baeldung.com/articles?topic=java&version=8"); + assertEquals("/articles", url.getPath()); + } + + @Test + public void givenUrl_whenCanGetQueryParams_thenCorrect() throws MalformedURLException { + final URL url = new URL("http://baeldung.com/articles?topic=java"); + assertEquals("topic=java", url.getQuery()); + } + + @Test + public void givenUrl_whenGetsDefaultPort_thenCorrect() throws MalformedURLException { + final URL url = new URL("http://baeldung.com"); + assertEquals(-1, url.getPort()); + assertEquals(80, url.getDefaultPort()); + } + + @Test + public void givenUrl_whenGetsPort_thenCorrect() throws MalformedURLException { + final URL url = new URL("http://baeldung.com:8090"); + assertEquals(8090, url.getPort()); + assertEquals(80, url.getDefaultPort()); + } + + @Test + public void givenBaseUrl_whenCreatesRelativeUrl_thenCorrect() throws MalformedURLException { + final URL baseUrl = new URL("http://baeldung.com"); + final URL relativeUrl = new URL(baseUrl, "a-guide-to-java-sockets"); + assertEquals("http://baeldung.com/a-guide-to-java-sockets", relativeUrl.toString()); + } + + @Test + public void givenAbsoluteUrl_whenIgnoresBaseUrl_thenCorrect() throws MalformedURLException { + final URL baseUrl = new URL("http://baeldung.com"); + final URL relativeUrl = new URL(baseUrl, "http://baeldung.com/a-guide-to-java-sockets"); + assertEquals("http://baeldung.com/a-guide-to-java-sockets", relativeUrl.toString()); + } + + @Test + public void givenUrlComponents_whenConstructsCompleteUrl_thenCorrect() throws MalformedURLException { + final String protocol = "http"; + final String host = "baeldung.com"; + final String file = "/guidelines.txt"; + final URL url = new URL(protocol, host, file); + assertEquals("http://baeldung.com/guidelines.txt", url.toString()); + } + + @Test + public void givenUrlComponents_whenConstructsCompleteUrl_thenCorrect2() throws MalformedURLException { + final String protocol = "http"; + final String host = "baeldung.com"; + final String file = "/articles?topic=java&version=8"; + final URL url = new URL(protocol, host, file); + assertEquals("http://baeldung.com/articles?topic=java&version=8", url.toString()); + } + + @Test + public void givenUrlComponentsWithPort_whenConstructsCompleteUrl_thenCorrect() throws MalformedURLException { + final String protocol = "http"; + final String host = "baeldung.com"; + final int port = 9000; + final String file = "/guidelines.txt"; + final URL url = new URL(protocol, host, port, file); + assertEquals("http://baeldung.com:9000/guidelines.txt", url.toString()); + } + +} diff --git a/core-java/src/test/java/com/baeldung/java/nio/selector/NioEchoIntegrationTest.java b/core-java/src/test/java/com/baeldung/java/nio/selector/NioEchoIntegrationTest.java new file mode 100644 index 0000000000..fc64799578 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/nio/selector/NioEchoIntegrationTest.java @@ -0,0 +1,35 @@ +package com.baeldung.java.nio.selector; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class NioEchoIntegrationTest { + + Process server; + EchoClient client; + + @Before + public void setup() throws IOException, InterruptedException { + server = EchoServer.start(); + client = EchoClient.start(); + } + + @Test + public void givenServerClient_whenServerEchosMessage_thenCorrect() { + String resp1 = client.sendMessage("hello"); + String resp2 = client.sendMessage("world"); + assertEquals("hello", resp1); + assertEquals("world", resp2); + } + + @After + public void teardown() throws IOException { + server.destroy(); + EchoClient.stop(); + } +} diff --git a/core-java/src/test/java/com/baeldung/java/nio2/FileTest.java b/core-java/src/test/java/com/baeldung/java/nio2/FileTest.java new file mode 100644 index 0000000000..64fbb4ae25 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/nio2/FileTest.java @@ -0,0 +1,246 @@ +package com.baeldung.java.nio2; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.nio.file.DirectoryNotEmptyException; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.UUID; + +import org.junit.Test; + +public class FileTest { + private static final String HOME = System.getProperty("user.home"); + + // checking file or dir + @Test + public void givenExistentPath_whenConfirmsFileExists_thenCorrect() { + Path p = Paths.get(HOME); + assertTrue(Files.exists(p)); + } + + @Test + public void givenNonexistentPath_whenConfirmsFileNotExists_thenCorrect() { + Path p = Paths.get(HOME + "/inexistent_file.txt"); + assertTrue(Files.notExists(p)); + } + + @Test + public void givenDirPath_whenConfirmsNotRegularFile_thenCorrect() { + Path p = Paths.get(HOME); + assertFalse(Files.isRegularFile(p)); + } + + @Test + public void givenExistentDirPath_whenConfirmsReadable_thenCorrect() { + Path p = Paths.get(HOME); + assertTrue(Files.isReadable(p)); + } + + @Test + public void givenExistentDirPath_whenConfirmsWritable_thenCorrect() { + Path p = Paths.get(HOME); + assertTrue(Files.isWritable(p)); + } + + @Test + public void givenExistentDirPath_whenConfirmsExecutable_thenCorrect() { + Path p = Paths.get(HOME); + assertTrue(Files.isExecutable(p)); + } + + @Test + public void givenSameFilePaths_whenConfirmsIsSame_thenCorrect() throws IOException { + Path p1 = Paths.get(HOME); + Path p2 = Paths.get(HOME); + assertTrue(Files.isSameFile(p1, p2)); + } + + // reading, writing and creating files + // creating file + @Test + public void givenFilePath_whenCreatesNewFile_thenCorrect() throws IOException { + String fileName = "myfile_" + UUID.randomUUID().toString() + ".txt"; + Path p = Paths.get(HOME + "/" + fileName); + assertFalse(Files.exists(p)); + Files.createFile(p); + assertTrue(Files.exists(p)); + + } + + @Test + public void givenDirPath_whenCreatesNewDir_thenCorrect() throws IOException { + String dirName = "myDir_" + UUID.randomUUID().toString(); + Path p = Paths.get(HOME + "/" + dirName); + assertFalse(Files.exists(p)); + Files.createDirectory(p); + assertTrue(Files.exists(p)); + assertFalse(Files.isRegularFile(p)); + assertTrue(Files.isDirectory(p)); + + } + + @Test(expected = NoSuchFileException.class) + public void givenDirPath_whenFailsToCreateRecursively_thenCorrect() throws IOException { + String dirName = "myDir_" + UUID.randomUUID().toString() + "/subdir"; + Path p = Paths.get(HOME + "/" + dirName); + assertFalse(Files.exists(p)); + Files.createDirectory(p); + + } + + @Test + public void givenDirPath_whenCreatesRecursively_thenCorrect() throws IOException { + Path dir = Paths.get(HOME + "/myDir_" + UUID.randomUUID().toString()); + Path subdir = dir.resolve("subdir"); + assertFalse(Files.exists(dir)); + assertFalse(Files.exists(subdir)); + Files.createDirectories(subdir); + assertTrue(Files.exists(dir)); + assertTrue(Files.exists(subdir)); + } + + @Test + public void givenFilePath_whenCreatesTempFile_thenCorrect() throws IOException { + String prefix = "log_"; + String suffix = ".txt"; + Path p = Paths.get(HOME + "/"); + p = Files.createTempFile(p, prefix, suffix); + // like log_8821081429012075286.txt + assertTrue(Files.exists(p)); + + } + + @Test + public void givenPath_whenCreatesTempFileWithDefaults_thenCorrect() throws IOException { + Path p = Paths.get(HOME + "/"); + p = Files.createTempFile(p, null, null); + // like 8600179353689423985.tmp + assertTrue(Files.exists(p)); + } + + @Test + public void givenNoFilePath_whenCreatesTempFileInTempDir_thenCorrect() throws IOException { + Path p = Files.createTempFile(null, null); + // like C:\Users\new\AppData\Local\Temp\6100927974988978748.tmp + assertTrue(Files.exists(p)); + + } + + // delete file + @Test + public void givenPath_whenDeletes_thenCorrect() throws IOException { + Path p = Paths.get(HOME + "/fileToDelete.txt"); + assertFalse(Files.exists(p)); + Files.createFile(p); + assertTrue(Files.exists(p)); + Files.delete(p); + assertFalse(Files.exists(p)); + + } + + @Test(expected = DirectoryNotEmptyException.class) + public void givenPath_whenFailsToDeleteNonEmptyDir_thenCorrect() throws IOException { + Path dir = Paths.get(HOME + "/emptyDir" + UUID.randomUUID().toString()); + Files.createDirectory(dir); + assertTrue(Files.exists(dir)); + Path file = dir.resolve("file.txt"); + Files.createFile(file); + Files.delete(dir); + + assertTrue(Files.exists(dir)); + + } + + @Test(expected = NoSuchFileException.class) + public void givenInexistentFile_whenDeleteFails_thenCorrect() throws IOException { + Path p = Paths.get(HOME + "/inexistentFile.txt"); + assertFalse(Files.exists(p)); + Files.delete(p); + + } + + @Test + public void givenInexistentFile_whenDeleteIfExistsWorks_thenCorrect() throws IOException { + Path p = Paths.get(HOME + "/inexistentFile.txt"); + assertFalse(Files.exists(p)); + Files.deleteIfExists(p); + + } + + // copy file + @Test + public void givenFilePath_whenCopiesToNewLocation_thenCorrect() throws IOException { + Path dir1 = Paths.get(HOME + "/firstdir_" + UUID.randomUUID().toString()); + Path dir2 = Paths.get(HOME + "/otherdir_" + UUID.randomUUID().toString()); + Files.createDirectory(dir1); + Files.createDirectory(dir2); + Path file1 = dir1.resolve("filetocopy.txt"); + Path file2 = dir2.resolve("filetocopy.txt"); + Files.createFile(file1); + assertTrue(Files.exists(file1)); + assertFalse(Files.exists(file2)); + Files.copy(file1, file2); + assertTrue(Files.exists(file2)); + + } + + @Test(expected = FileAlreadyExistsException.class) + public void givenPath_whenCopyFailsDueToExistingFile_thenCorrect() throws IOException { + Path dir1 = Paths.get(HOME + "/firstdir_" + UUID.randomUUID().toString()); + Path dir2 = Paths.get(HOME + "/otherdir_" + UUID.randomUUID().toString()); + Files.createDirectory(dir1); + Files.createDirectory(dir2); + Path file1 = dir1.resolve("filetocopy.txt"); + Path file2 = dir2.resolve("filetocopy.txt"); + Files.createFile(file1); + Files.createFile(file2); + assertTrue(Files.exists(file1)); + assertTrue(Files.exists(file2)); + Files.copy(file1, file2); + Files.copy(file1, file2, StandardCopyOption.REPLACE_EXISTING); + } + + // moving files + @Test + public void givenFilePath_whenMovesToNewLocation_thenCorrect() throws IOException { + Path dir1 = Paths.get(HOME + "/firstdir_" + UUID.randomUUID().toString()); + Path dir2 = Paths.get(HOME + "/otherdir_" + UUID.randomUUID().toString()); + Files.createDirectory(dir1); + Files.createDirectory(dir2); + Path file1 = dir1.resolve("filetocopy.txt"); + Path file2 = dir2.resolve("filetocopy.txt"); + Files.createFile(file1); + assertTrue(Files.exists(file1)); + assertFalse(Files.exists(file2)); + Files.move(file1, file2); + assertTrue(Files.exists(file2)); + assertFalse(Files.exists(file1)); + + } + + @Test(expected = FileAlreadyExistsException.class) + public void givenFilePath_whenMoveFailsDueToExistingFile_thenCorrect() throws IOException { + Path dir1 = Paths.get(HOME + "/firstdir_" + UUID.randomUUID().toString()); + Path dir2 = Paths.get(HOME + "/otherdir_" + UUID.randomUUID().toString()); + Files.createDirectory(dir1); + Files.createDirectory(dir2); + Path file1 = dir1.resolve("filetocopy.txt"); + Path file2 = dir2.resolve("filetocopy.txt"); + Files.createFile(file1); + Files.createFile(file2); + assertTrue(Files.exists(file1)); + assertTrue(Files.exists(file2)); + Files.move(file1, file2); + Files.move(file1, file2, StandardCopyOption.REPLACE_EXISTING); + assertTrue(Files.exists(file2)); + assertFalse(Files.exists(file1)); + } + +} diff --git a/core-java/src/test/java/com/baeldung/java/nio2/PathManualTest.java b/core-java/src/test/java/com/baeldung/java/nio2/PathManualTest.java new file mode 100644 index 0000000000..acfb2c08e9 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/nio2/PathManualTest.java @@ -0,0 +1,195 @@ +package com.baeldung.java.nio2; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.net.URI; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Date; + +import org.junit.Test; + +public class PathManualTest { + + private static final String HOME = System.getProperty("user.home"); + + // creating a path + @Test + public void givenPathString_whenCreatesPathObject_thenCorrect() { + Path p = Paths.get("/articles/baeldung"); + assertEquals("\\articles\\baeldung", p.toString()); + + } + + @Test + public void givenPathParts_whenCreatesPathObject_thenCorrect() { + Path p = Paths.get("/articles", "baeldung"); + assertEquals("\\articles\\baeldung", p.toString()); + + } + + // retrieving path info + @Test + public void givenPath_whenRetrievesFileName_thenCorrect() { + Path p = Paths.get("/articles/baeldung/logs"); + assertEquals("logs", p.getFileName().toString()); + } + + @Test + public void givenPath_whenRetrievesNameByIndex_thenCorrect() { + Path p = Paths.get("/articles/baeldung/logs"); + assertEquals("articles", p.getName(0).toString()); + assertEquals("baeldung", p.getName(1).toString()); + assertEquals("logs", p.getName(2).toString()); + } + + @Test + public void givenPath_whenCountsParts_thenCorrect() { + Path p = Paths.get("/articles/baeldung/logs"); + assertEquals(3, p.getNameCount()); + } + + @Test + public void givenPath_whenCanRetrieveSubsequenceByIndex_thenCorrect() { + Path p = Paths.get("/articles/baeldung/logs"); + assertEquals("articles", p.subpath(0, 1).toString()); + assertEquals("articles\\baeldung", p.subpath(0, 2).toString()); + assertEquals("articles\\baeldung\\logs", p.subpath(0, 3).toString()); + assertEquals("baeldung", p.subpath(1, 2).toString()); + assertEquals("baeldung\\logs", p.subpath(1, 3).toString()); + assertEquals("logs", p.subpath(2, 3).toString()); + } + + @Test + public void givenPath_whenRetrievesParent_thenCorrect() { + Path p1 = Paths.get("/articles/baeldung/logs"); + Path p2 = Paths.get("/articles/baeldung"); + Path p3 = Paths.get("/articles"); + Path p4 = Paths.get("/"); + + assertEquals("\\articles\\baeldung", p1.getParent().toString()); + assertEquals("\\articles", p2.getParent().toString()); + assertEquals("\\", p3.getParent().toString()); + assertEquals(null, p4.getParent()); + } + + @Test + public void givenPath_whenRetrievesRoot_thenCorrect() { + Path p1 = Paths.get("/articles/baeldung/logs"); + Path p2 = Paths.get("c:/articles/baeldung/logs"); + + assertEquals("\\", p1.getRoot().toString()); + assertEquals("c:\\", p2.getRoot().toString()); + } + + // removing redundancies from path + @Test + public void givenPath_whenRemovesRedundancies_thenCorrect1() { + Path p = Paths.get("/home/./baeldung/articles"); + p = p.normalize(); + assertEquals("\\home\\baeldung\\articles", p.toString()); + } + + @Test + public void givenPath_whenRemovesRedundancies_thenCorrect2() { + Path p = Paths.get("/home/baeldung/../articles"); + p = p.normalize(); + assertEquals("\\home\\articles", p.toString()); + } + + // converting a path + @Test + public void givenPath_whenConvertsToBrowseablePath_thenCorrect() { + Path p = Paths.get("/home/baeldung/articles.html"); + URI uri = p.toUri(); + assertEquals("file:///E:/home/baeldung/articles.html", uri.toString()); + } + + @Test + public void givenPath_whenConvertsToAbsolutePath_thenCorrect() { + Path p = Paths.get("/home/baeldung/articles.html"); + assertEquals("E:\\home\\baeldung\\articles.html", p.toAbsolutePath().toString()); + } + + @Test + public void givenAbsolutePath_whenRetainsAsAbsolute_thenCorrect() { + Path p = Paths.get("E:\\home\\baeldung\\articles.html"); + assertEquals("E:\\home\\baeldung\\articles.html", p.toAbsolutePath().toString()); + } + + @Test + public void givenExistingPath_whenGetsRealPathToFile_thenCorrect() throws IOException { + Path p = Paths.get(HOME); + assertEquals(HOME, p.toRealPath().toString()); + } + + @Test(expected = NoSuchFileException.class) + public void givenInExistentPath_whenFailsToConvert_thenCorrect() throws IOException { + Path p = Paths.get("E:\\home\\baeldung\\articles.html"); + + p.toRealPath(); + } + + // joining paths + @Test + public void givenTwoPaths_whenJoinsAndResolves_thenCorrect() throws IOException { + Path p = Paths.get("/baeldung/articles"); + assertEquals("\\baeldung\\articles\\java", p.resolve("java").toString()); + } + + @Test + public void givenAbsolutePath_whenResolutionRetainsIt_thenCorrect() throws IOException { + Path p = Paths.get("/baeldung/articles"); + assertEquals("C:\\baeldung\\articles\\java", p.resolve("C:\\baeldung\\articles\\java").toString()); + } + + @Test + public void givenPathWithRoot_whenResolutionRetainsIt_thenCorrect2() throws IOException { + Path p = Paths.get("/baeldung/articles"); + assertEquals("\\java", p.resolve("/java").toString()); + } + + // creating a path between 2 paths + @Test + public void givenSiblingPaths_whenCreatesPathToOther_thenCorrect() throws IOException { + Path p1 = Paths.get("articles"); + Path p2 = Paths.get("authors"); + assertEquals("..\\authors", p1.relativize(p2).toString()); + assertEquals("..\\articles", p2.relativize(p1).toString()); + } + + @Test + public void givenNonSiblingPaths_whenCreatesPathToOther_thenCorrect() throws IOException { + Path p1 = Paths.get("/baeldung"); + Path p2 = Paths.get("/baeldung/authors/articles"); + assertEquals("authors\\articles", p1.relativize(p2).toString()); + assertEquals("..\\..", p2.relativize(p1).toString()); + } + + // comparing 2 paths + @Test + public void givenTwoPaths_whenTestsEquality_thenCorrect() throws IOException { + Path p1 = Paths.get("/baeldung/articles"); + Path p2 = Paths.get("/baeldung/articles"); + Path p3 = Paths.get("/baeldung/authors"); + + assertTrue(p1.equals(p2)); + assertFalse(p1.equals(p3)); + } + + @Test + public void givenPath_whenInspectsStart_thenCorrect() { + Path p1 = Paths.get("/baeldung/articles"); + assertTrue(p1.startsWith("/baeldung")); + } + + @Test + public void givenPath_whenInspectsEnd_thenCorrect() { + Path p1 = Paths.get("/baeldung/articles"); + assertTrue(p1.endsWith("articles")); + } +} diff --git a/core-java/src/test/java/com/baeldung/java/reflection/ReflectionUnitTest.java b/core-java/src/test/java/com/baeldung/java/reflection/ReflectionUnitTest.java new file mode 100644 index 0000000000..0c090901e7 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/reflection/ReflectionUnitTest.java @@ -0,0 +1,302 @@ +package com.baeldung.java.reflection; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class ReflectionUnitTest { + + @Test + public void givenObject_whenGetsFieldNamesAtRuntime_thenCorrect() { + final Object person = new Person(); + final Field[] fields = person.getClass().getDeclaredFields(); + + final List actualFieldNames = getFieldNames(fields); + + assertTrue(Arrays.asList("name", "age").containsAll(actualFieldNames)); + } + + @Test + public void givenObject_whenGetsClassName_thenCorrect() { + final Object goat = new Goat("goat"); + final Class clazz = goat.getClass(); + + assertEquals("Goat", clazz.getSimpleName()); + assertEquals("com.baeldung.java.reflection.Goat", clazz.getName()); + assertEquals("com.baeldung.java.reflection.Goat", clazz.getCanonicalName()); + } + + @Test + public void givenClassName_whenCreatesObject_thenCorrect() throws ClassNotFoundException { + final Class clazz = Class.forName("com.baeldung.java.reflection.Goat"); + + assertEquals("Goat", clazz.getSimpleName()); + assertEquals("com.baeldung.java.reflection.Goat", clazz.getName()); + assertEquals("com.baeldung.java.reflection.Goat", clazz.getCanonicalName()); + } + + @Test + public void givenClass_whenRecognisesModifiers_thenCorrect() throws ClassNotFoundException { + final Class goatClass = Class.forName("com.baeldung.java.reflection.Goat"); + final Class animalClass = Class.forName("com.baeldung.java.reflection.Animal"); + final int goatMods = goatClass.getModifiers(); + final int animalMods = animalClass.getModifiers(); + + assertTrue(Modifier.isPublic(goatMods)); + assertTrue(Modifier.isAbstract(animalMods)); + assertTrue(Modifier.isPublic(animalMods)); + } + + @Test + public void givenClass_whenGetsPackageInfo_thenCorrect() { + final Goat goat = new Goat("goat"); + final Class goatClass = goat.getClass(); + final Package pkg = goatClass.getPackage(); + + assertEquals("com.baeldung.java.reflection", pkg.getName()); + } + + @Test + public void givenClass_whenGetsSuperClass_thenCorrect() { + final Goat goat = new Goat("goat"); + final String str = "any string"; + + final Class goatClass = goat.getClass(); + final Class goatSuperClass = goatClass.getSuperclass(); + + assertEquals("Animal", goatSuperClass.getSimpleName()); + assertEquals("Object", str.getClass().getSuperclass().getSimpleName()); + + } + + @Test + public void givenClass_whenGetsImplementedInterfaces_thenCorrect() throws ClassNotFoundException { + final Class goatClass = Class.forName("com.baeldung.java.reflection.Goat"); + final Class animalClass = Class.forName("com.baeldung.java.reflection.Animal"); + final Class[] goatInterfaces = goatClass.getInterfaces(); + final Class[] animalInterfaces = animalClass.getInterfaces(); + + assertEquals(1, goatInterfaces.length); + assertEquals(1, animalInterfaces.length); + assertEquals("Locomotion", goatInterfaces[0].getSimpleName()); + assertEquals("Eating", animalInterfaces[0].getSimpleName()); + } + + @Test + public void givenClass_whenGetsConstructor_thenCorrect() throws ClassNotFoundException { + final Class goatClass = Class.forName("com.baeldung.java.reflection.Goat"); + final Constructor[] constructors = goatClass.getConstructors(); + + assertEquals(1, constructors.length); + assertEquals("com.baeldung.java.reflection.Goat", constructors[0].getName()); + } + + @Test + public void givenClass_whenGetsFields_thenCorrect() throws ClassNotFoundException { + final Class animalClass = Class.forName("com.baeldung.java.reflection.Animal"); + final Field[] fields = animalClass.getDeclaredFields(); + + final List actualFields = getFieldNames(fields); + + assertEquals(2, actualFields.size()); + assertTrue(actualFields.containsAll(Arrays.asList("name", "CATEGORY"))); + } + + @Test + public void givenClass_whenGetsMethods_thenCorrect() throws ClassNotFoundException { + final Class animalClass = Class.forName("com.baeldung.java.reflection.Animal"); + final Method[] methods = animalClass.getDeclaredMethods(); + final List actualMethods = getMethodNames(methods); + + assertEquals(3, actualMethods.size()); + assertTrue(actualMethods.containsAll(Arrays.asList("getName", "setName", "getSound"))); + } + + @Test + public void givenClass_whenGetsAllConstructors_thenCorrect() throws ClassNotFoundException { + final Class birdClass = Class.forName("com.baeldung.java.reflection.Bird"); + final Constructor[] constructors = birdClass.getConstructors(); + + assertEquals(3, constructors.length); + } + + @Test + public void givenClass_whenGetsEachConstructorByParamTypes_thenCorrect() throws Exception { + final Class birdClass = Class.forName("com.baeldung.java.reflection.Bird"); + birdClass.getConstructor(); + birdClass.getConstructor(String.class); + birdClass.getConstructor(String.class, boolean.class); + } + + @Test + public void givenClass_whenInstantiatesObjectsAtRuntime_thenCorrect() throws Exception { + final Class birdClass = Class.forName("com.baeldung.java.reflection.Bird"); + + final Constructor cons1 = birdClass.getConstructor(); + final Constructor cons2 = birdClass.getConstructor(String.class); + final Constructor cons3 = birdClass.getConstructor(String.class, boolean.class); + + final Bird bird1 = (Bird) cons1.newInstance(); + final Bird bird2 = (Bird) cons2.newInstance("Weaver bird"); + final Bird bird3 = (Bird) cons3.newInstance("dove", true); + + assertEquals("bird", bird1.getName()); + assertEquals("Weaver bird", bird2.getName()); + assertEquals("dove", bird3.getName()); + assertFalse(bird1.walks()); + assertTrue(bird3.walks()); + } + + @Test + public void givenClass_whenGetsPublicFields_thenCorrect() throws ClassNotFoundException { + final Class birdClass = Class.forName("com.baeldung.java.reflection.Bird"); + final Field[] fields = birdClass.getFields(); + assertEquals(1, fields.length); + assertEquals("CATEGORY", fields[0].getName()); + + } + + @Test + public void givenClass_whenGetsPublicFieldByName_thenCorrect() throws Exception { + final Class birdClass = Class.forName("com.baeldung.java.reflection.Bird"); + final Field field = birdClass.getField("CATEGORY"); + assertEquals("CATEGORY", field.getName()); + + } + + @Test + public void givenClass_whenGetsDeclaredFields_thenCorrect() throws ClassNotFoundException { + final Class birdClass = Class.forName("com.baeldung.java.reflection.Bird"); + final Field[] fields = birdClass.getDeclaredFields(); + assertEquals(1, fields.length); + assertEquals("walks", fields[0].getName()); + } + + @Test + public void givenClass_whenGetsFieldsByName_thenCorrect() throws Exception { + final Class birdClass = Class.forName("com.baeldung.java.reflection.Bird"); + final Field field = birdClass.getDeclaredField("walks"); + assertEquals("walks", field.getName()); + + } + + @Test + public void givenClassField_whenGetsType_thenCorrect() throws Exception { + final Field field = Class.forName("com.baeldung.java.reflection.Bird").getDeclaredField("walks"); + final Class fieldClass = field.getType(); + assertEquals("boolean", fieldClass.getSimpleName()); + } + + @Test + public void givenClassField_whenSetsAndGetsValue_thenCorrect() throws Exception { + final Class birdClass = Class.forName("com.baeldung.java.reflection.Bird"); + final Bird bird = (Bird) birdClass.newInstance(); + final Field field = birdClass.getDeclaredField("walks"); + field.setAccessible(true); + + assertFalse(field.getBoolean(bird)); + assertFalse(bird.walks()); + + field.set(bird, true); + + assertTrue(field.getBoolean(bird)); + assertTrue(bird.walks()); + + } + + @Test + public void givenClassField_whenGetsAndSetsWithNull_thenCorrect() throws Exception { + final Class birdClass = Class.forName("com.baeldung.java.reflection.Bird"); + final Field field = birdClass.getField("CATEGORY"); + field.setAccessible(true); + + assertEquals("domestic", field.get(null)); + } + + @Test + public void givenClass_whenGetsAllPublicMethods_thenCorrect() throws ClassNotFoundException { + final Class birdClass = Class.forName("com.baeldung.java.reflection.Bird"); + final Method[] methods = birdClass.getMethods(); + final List methodNames = getMethodNames(methods); + + assertTrue(methodNames.containsAll(Arrays.asList("equals", "notifyAll", "hashCode", "walks", "eats", "toString"))); + + } + + @Test + public void givenClass_whenGetsOnlyDeclaredMethods_thenCorrect() throws ClassNotFoundException { + final Class birdClass = Class.forName("com.baeldung.java.reflection.Bird"); + final List actualMethodNames = getMethodNames(birdClass.getDeclaredMethods()); + + final List expectedMethodNames = Arrays.asList("setWalks", "walks", "getSound", "eats"); + + assertEquals(expectedMethodNames.size(), actualMethodNames.size()); + assertTrue(expectedMethodNames.containsAll(actualMethodNames)); + assertTrue(actualMethodNames.containsAll(expectedMethodNames)); + + } + + @Test + public void givenMethodName_whenGetsMethod_thenCorrect() throws Exception { + final Class birdClass = Class.forName("com.baeldung.java.reflection.Bird"); + final Method walksMethod = birdClass.getDeclaredMethod("walks"); + final Method setWalksMethod = birdClass.getDeclaredMethod("setWalks", boolean.class); + + assertFalse(walksMethod.isAccessible()); + assertFalse(setWalksMethod.isAccessible()); + + walksMethod.setAccessible(true); + setWalksMethod.setAccessible(true); + + assertTrue(walksMethod.isAccessible()); + assertTrue(setWalksMethod.isAccessible()); + + } + + @Test + public void givenMethod_whenInvokes_thenCorrect() throws Exception { + final Class birdClass = Class.forName("com.baeldung.java.reflection.Bird"); + final Bird bird = (Bird) birdClass.newInstance(); + final Method setWalksMethod = birdClass.getDeclaredMethod("setWalks", boolean.class); + final Method walksMethod = birdClass.getDeclaredMethod("walks"); + final boolean walks = (boolean) walksMethod.invoke(bird); + + assertFalse(walks); + assertFalse(bird.walks()); + + setWalksMethod.invoke(bird, true); + final boolean walks2 = (boolean) walksMethod.invoke(bird); + + assertTrue(walks2); + assertTrue(bird.walks()); + + } + + private static List getFieldNames(Field[] fields) { + final List fieldNames = new ArrayList<>(); + for (final Field field : fields) { + fieldNames.add(field.getName()); + } + return fieldNames; + + } + + private static List getMethodNames(Method[] methods) { + final List methodNames = new ArrayList<>(); + for (final Method method : methods) { + methodNames.add(method.getName()); + } + return methodNames; + } + +} diff --git a/core-java/src/test/java/com/baeldung/java/regex/RegexUnitTest.java b/core-java/src/test/java/com/baeldung/java/regex/RegexUnitTest.java new file mode 100644 index 0000000000..e4ea55aae3 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/regex/RegexUnitTest.java @@ -0,0 +1,501 @@ +package com.baeldung.java.regex; + +import static org.junit.Assert.*; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.Test; + +public class RegexUnitTest { + private static Pattern pattern; + private static Matcher matcher; + + @Test + public void givenText_whenSimpleRegexMatches_thenCorrect() { + Pattern pattern = Pattern.compile("foo"); + Matcher matcher = pattern.matcher("foo"); + assertTrue(matcher.find()); + } + + @Test + public void givenText_whenSimpleRegexMatchesTwice_thenCorrect() { + Pattern pattern = Pattern.compile("foo"); + Matcher matcher = pattern.matcher("foofoo"); + int matches = 0; + while (matcher.find()) + matches++; + assertEquals(matches, 2); + + } + + @Test + public void givenText_whenMatchesWithDotMetach_thenCorrect() { + int matches = runTest(".", "foo"); + assertTrue(matches > 0); + } + + @Test + public void givenRepeatedText_whenMatchesOnceWithDotMetach_thenCorrect() { + int matches = runTest("foo.", "foofoo"); + assertTrue(matches > 0); + assertEquals(matches, 1); + } + + @Test + public void givenORSet_whenMatchesAny_thenCorrect() { + int matches = runTest("[abc]", "b"); + assertTrue(matches > 0); + assertEquals(matches, 1); + } + + @Test + public void givenORSet_whenMatchesAnyAndAll_thenCorrect() { + int matches = runTest("[abc]", "cab"); + assertTrue(matches > 0); + assertEquals(matches, 3); + } + + @Test + public void givenORSet_whenMatchesAllCombinations_thenCorrect() { + int matches = runTest("[bcr]at", "bat cat rat"); + assertTrue(matches > 0); + assertEquals(matches, 3); + } + + @Test + public void givenNORSet_whenMatchesNon_thenCorrect() { + int matches = runTest("[^abc]", "g"); + assertTrue(matches > 0); + } + + @Test + public void givenNORSet_whenMatchesAllExceptElements_thenCorrect() { + int matches = runTest("[^bcr]at", "sat mat eat"); + assertTrue(matches > 0); + } + + @Test + public void givenUpperCaseRange_whenMatchesUpperCase_thenCorrect() { + int matches = runTest("[A-Z]", "Two Uppercase alphabets 34 overall"); + assertTrue(matches > 0); + assertEquals(matches, 2); + } + + @Test + public void givenLowerCaseRange_whenMatchesLowerCase_thenCorrect() { + int matches = runTest("[a-z]", "Two Uppercase alphabets 34 overall"); + assertTrue(matches > 0); + assertEquals(matches, 26); + } + + @Test + public void givenBothLowerAndUpperCaseRange_whenMatchesAllLetters_thenCorrect() { + int matches = runTest("[a-zA-Z]", "Two Uppercase alphabets 34 overall"); + assertTrue(matches > 0); + assertEquals(matches, 28); + } + + @Test + public void givenNumberRange_whenMatchesAccurately_thenCorrect() { + int matches = runTest("[1-5]", "Two Uppercase alphabets 34 overall"); + assertTrue(matches > 0); + assertEquals(matches, 2); + } + + @Test + public void givenNumberRange_whenMatchesAccurately_thenCorrect2() { + int matches = runTest("[30-35]", "Two Uppercase alphabets 34 overall"); + assertTrue(matches > 0); + assertEquals(matches, 1); + } + + @Test + public void givenTwoSets_whenMatchesUnion_thenCorrect() { + int matches = runTest("[1-3[7-9]]", "123456789"); + assertTrue(matches > 0); + assertEquals(matches, 6); + } + + @Test + public void givenTwoSets_whenMatchesIntersection_thenCorrect() { + int matches = runTest("[1-6&&[3-9]]", "123456789"); + assertTrue(matches > 0); + assertEquals(matches, 4); + } + + @Test + public void givenSetWithSubtraction_whenMatchesAccurately_thenCorrect() { + int matches = runTest("[0-9&&[^2468]]", "123456789"); + assertTrue(matches > 0); + assertEquals(matches, 5); + } + + @Test + public void givenDigits_whenMatches_thenCorrect() { + int matches = runTest("\\d", "123"); + assertTrue(matches > 0); + assertEquals(matches, 3); + } + + @Test + public void givenNonDigits_whenMatches_thenCorrect() { + int matches = runTest("\\D", "a6c"); + assertTrue(matches > 0); + assertEquals(matches, 2); + } + + @Test + public void givenWhiteSpace_whenMatches_thenCorrect() { + int matches = runTest("\\s", "a c"); + assertTrue(matches > 0); + assertEquals(matches, 1); + } + + @Test + public void givenNonWhiteSpace_whenMatches_thenCorrect() { + int matches = runTest("\\S", "a c"); + assertTrue(matches > 0); + assertEquals(matches, 2); + } + + @Test + public void givenWordCharacter_whenMatches_thenCorrect() { + int matches = runTest("\\w", "hi!"); + assertTrue(matches > 0); + assertEquals(matches, 2); + } + + @Test + public void givenNonWordCharacter_whenMatches_thenCorrect() { + int matches = runTest("\\W", "hi!"); + assertTrue(matches > 0); + assertEquals(matches, 1); + } + + @Test + public void givenZeroOrOneQuantifier_whenMatches_thenCorrect() { + int matches = runTest("\\a?", "hi"); + assertTrue(matches > 0); + assertEquals(matches, 3); + } + + @Test + public void givenZeroOrOneQuantifier_whenMatches_thenCorrect2() { + int matches = runTest("\\a{0,1}", "hi"); + assertTrue(matches > 0); + assertEquals(matches, 3); + } + + @Test + public void givenZeroOrManyQuantifier_whenMatches_thenCorrect() { + int matches = runTest("\\a*", "hi"); + assertTrue(matches > 0); + assertEquals(matches, 3); + } + + @Test + public void givenZeroOrManyQuantifier_whenMatches_thenCorrect2() { + int matches = runTest("\\a{0,}", "hi"); + assertTrue(matches > 0); + assertEquals(matches, 3); + } + + @Test + public void givenOneOrManyQuantifier_whenMatches_thenCorrect() { + int matches = runTest("\\a+", "hi"); + assertFalse(matches > 0); + } + + @Test + public void givenOneOrManyQuantifier_whenMatches_thenCorrect2() { + int matches = runTest("\\a{1,}", "hi"); + assertFalse(matches > 0); + } + + @Test + public void givenBraceQuantifier_whenMatches_thenCorrect() { + int matches = runTest("a{3}", "aaaaaa"); + assertTrue(matches > 0); + assertEquals(matches, 2); + } + + @Test + public void givenBraceQuantifier_whenFailsToMatch_thenCorrect() { + int matches = runTest("a{3}", "aa"); + assertFalse(matches > 0); + } + + @Test + public void givenBraceQuantifierWithRange_whenMatches_thenCorrect() { + int matches = runTest("a{2,3}", "aaaa"); + assertTrue(matches > 0); + assertEquals(matches, 1); + } + + @Test + public void givenBraceQuantifierWithRange_whenMatchesLazily_thenCorrect() { + int matches = runTest("a{2,3}?", "aaaa"); + assertTrue(matches > 0); + assertEquals(matches, 2); + } + + @Test + public void givenCapturingGroup_whenMatches_thenCorrect() { + int matches = runTest("(\\d\\d)", "12"); + assertTrue(matches > 0); + assertEquals(matches, 1); + } + + @Test + public void givenCapturingGroup_whenMatches_thenCorrect2() { + int matches = runTest("(\\d\\d)", "1212"); + assertTrue(matches > 0); + assertEquals(matches, 2); + } + + @Test + public void givenCapturingGroup_whenMatches_thenCorrect3() { + int matches = runTest("(\\d\\d)(\\d\\d)", "1212"); + assertTrue(matches > 0); + assertEquals(matches, 1); + } + + @Test + public void givenCapturingGroup_whenMatchesWithBackReference_thenCorrect() { + int matches = runTest("(\\d\\d)\\1", "1212"); + assertTrue(matches > 0); + assertEquals(matches, 1); + } + + @Test + public void givenCapturingGroup_whenMatchesWithBackReference_thenCorrect2() { + int matches = runTest("(\\d\\d)\\1\\1\\1", "12121212"); + assertTrue(matches > 0); + assertEquals(matches, 1); + } + + @Test + public void givenCapturingGroupAndWrongInput_whenMatchFailsWithBackReference_thenCorrect() { + int matches = runTest("(\\d\\d)\\1", "1213"); + assertFalse(matches > 0); + } + + @Test + public void givenText_whenMatchesAtBeginning_thenCorrect() { + int matches = runTest("^dog", "dogs are friendly"); + assertTrue(matches > 0); + } + + @Test + public void givenTextAndWrongInput_whenMatchFailsAtBeginning_thenCorrect() { + int matches = runTest("^dog", "are dogs are friendly?"); + assertFalse(matches > 0); + } + + @Test + public void givenText_whenMatchesAtEnd_thenCorrect() { + int matches = runTest("dog$", "Man's best friend is a dog"); + assertTrue(matches > 0); + } + + @Test + public void givenTextAndWrongInput_whenMatchFailsAtEnd_thenCorrect() { + int matches = runTest("dog$", "is a dog man's best friend?"); + assertFalse(matches > 0); + } + + @Test + public void givenText_whenMatchesAtWordBoundary_thenCorrect() { + int matches = runTest("\\bdog\\b", "a dog is friendly"); + assertTrue(matches > 0); + } + + @Test + public void givenText_whenMatchesAtWordBoundary_thenCorrect2() { + int matches = runTest("\\bdog\\b", "dog is man's best friend"); + assertTrue(matches > 0); + } + + @Test + public void givenWrongText_whenMatchFailsAtWordBoundary_thenCorrect() { + int matches = runTest("\\bdog\\b", "snoop dogg is a rapper"); + assertFalse(matches > 0); + } + + @Test + public void givenText_whenMatchesAtWordAndNonBoundary_thenCorrect() { + int matches = runTest("\\bdog\\B", "snoop dogg is a rapper"); + assertTrue(matches > 0); + } + + @Test + public void givenRegexWithoutCanonEq_whenMatchFailsOnEquivalentUnicode_thenCorrect() { + int matches = runTest("\u00E9", "\u0065\u0301"); + assertFalse(matches > 0); + } + + @Test + public void givenRegexWithCanonEq_whenMatchesOnEquivalentUnicode_thenCorrect() { + int matches = runTest("\u00E9", "\u0065\u0301", Pattern.CANON_EQ); + assertTrue(matches > 0); + } + + @Test + public void givenRegexWithDefaultMatcher_whenMatchFailsOnDifferentCases_thenCorrect() { + int matches = runTest("dog", "This is a Dog"); + assertFalse(matches > 0); + } + + @Test + public void givenRegexWithCaseInsensitiveMatcher_whenMatchesOnDifferentCases_thenCorrect() { + int matches = runTest("dog", "This is a Dog", Pattern.CASE_INSENSITIVE); + assertTrue(matches > 0); + } + + @Test + public void givenRegexWithEmbeddedCaseInsensitiveMatcher_whenMatchesOnDifferentCases_thenCorrect() { + int matches = runTest("(?i)dog", "This is a Dog"); + assertTrue(matches > 0); + } + + @Test + public void givenRegexWithComments_whenMatchFailsWithoutFlag_thenCorrect() { + int matches = runTest("dog$ #check for word dog at end of text", "This is a dog"); + assertFalse(matches > 0); + } + + @Test + public void givenRegexWithComments_whenMatchesWithFlag_thenCorrect() { + int matches = runTest("dog$ #check for word dog at end of text", "This is a dog", Pattern.COMMENTS); + assertTrue(matches > 0); + } + + @Test + public void givenRegexWithComments_whenMatchesWithEmbeddedFlag_thenCorrect() { + int matches = runTest("(?x)dog$ #check for word dog at end of text", "This is a dog"); + assertTrue(matches > 0); + } + + @Test + public void givenRegexWithLineTerminator_whenMatchFails_thenCorrect() { + Pattern pattern = Pattern.compile("(.*)"); + Matcher matcher = pattern.matcher("this is a text" + System.getProperty("line.separator") + " continued on another line"); + matcher.find(); + assertEquals("this is a text", matcher.group(1)); + } + + @Test + public void givenRegexWithLineTerminator_whenMatchesWithDotall_thenCorrect() { + Pattern pattern = Pattern.compile("(.*)", Pattern.DOTALL); + Matcher matcher = pattern.matcher("this is a text" + System.getProperty("line.separator") + " continued on another line"); + matcher.find(); + assertEquals("this is a text" + System.getProperty("line.separator") + " continued on another line", matcher.group(1)); + } + + @Test + public void givenRegexWithLineTerminator_whenMatchesWithEmbeddedDotall_thenCorrect() { + Pattern pattern = Pattern.compile("(?s)(.*)"); + Matcher matcher = pattern.matcher("this is a text" + System.getProperty("line.separator") + " continued on another line"); + matcher.find(); + assertEquals("this is a text" + System.getProperty("line.separator") + " continued on another line", matcher.group(1)); + } + + @Test + public void givenRegex_whenMatchesWithoutLiteralFlag_thenCorrect() { + int matches = runTest("(.*)", "text"); + assertTrue(matches > 0); + } + + @Test + public void givenRegex_whenMatchFailsWithLiteralFlag_thenCorrect() { + int matches = runTest("(.*)", "text", Pattern.LITERAL); + assertFalse(matches > 0); + } + + @Test + public void givenRegex_whenMatchesWithLiteralFlag_thenCorrect() { + int matches = runTest("(.*)", "text(.*)", Pattern.LITERAL); + assertTrue(matches > 0); + } + + @Test + public void givenRegex_whenMatchFailsWithoutMultilineFlag_thenCorrect() { + int matches = runTest("dog$", "This is a dog" + System.getProperty("line.separator") + "this is a fox"); + assertFalse(matches > 0); + } + + @Test + public void givenRegex_whenMatchesWithMultilineFlag_thenCorrect() { + int matches = runTest("dog$", "This is a dog" + System.getProperty("line.separator") + "this is a fox", Pattern.MULTILINE); + assertTrue(matches > 0); + } + + @Test + public void givenRegex_whenMatchesWithEmbeddedMultilineFlag_thenCorrect() { + int matches = runTest("(?m)dog$", "This is a dog" + System.getProperty("line.separator") + "this is a fox"); + assertTrue(matches > 0); + } + + @Test + public void givenMatch_whenGetsIndices_thenCorrect() { + Pattern pattern = Pattern.compile("dog"); + Matcher matcher = pattern.matcher("This dog is mine"); + matcher.find(); + assertEquals(5, matcher.start()); + assertEquals(8, matcher.end()); + } + + @Test + public void whenStudyMethodsWork_thenCorrect() { + Pattern pattern = Pattern.compile("dog"); + Matcher matcher = pattern.matcher("dogs are friendly"); + assertTrue(matcher.lookingAt()); + assertFalse(matcher.matches()); + + } + + @Test + public void whenMatchesStudyMethodWorks_thenCorrect() { + Pattern pattern = Pattern.compile("dog"); + Matcher matcher = pattern.matcher("dog"); + assertTrue(matcher.matches()); + + } + + @Test + public void whenReplaceFirstWorks_thenCorrect() { + Pattern pattern = Pattern.compile("dog"); + Matcher matcher = pattern.matcher("dogs are domestic animals, dogs are friendly"); + String newStr = matcher.replaceFirst("cat"); + assertEquals("cats are domestic animals, dogs are friendly", newStr); + + } + + @Test + public void whenReplaceAllWorks_thenCorrect() { + Pattern pattern = Pattern.compile("dog"); + Matcher matcher = pattern.matcher("dogs are domestic animals, dogs are friendly"); + String newStr = matcher.replaceAll("cat"); + assertEquals("cats are domestic animals, cats are friendly", newStr); + + } + + public synchronized static int runTest(String regex, String text) { + pattern = Pattern.compile(regex); + matcher = pattern.matcher(text); + int matches = 0; + while (matcher.find()) + matches++; + return matches; + } + + public synchronized static int runTest(String regex, String text, int flags) { + pattern = Pattern.compile(regex, flags); + matcher = pattern.matcher(text); + int matches = 0; + while (matcher.find()) + matches++; + return matches; + } +} diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8CollectionCleanupUnitTest.java b/core-java/src/test/java/com/baeldung/java8/Java8CollectionCleanupUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/java8/Java8CollectionCleanupUnitTest.java rename to core-java/src/test/java/com/baeldung/java8/Java8CollectionCleanupUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8DefaultStaticIntefaceMethodsTest.java b/core-java/src/test/java/com/baeldung/java8/Java8DefaultStaticIntefaceMethodsUnitTest.java similarity index 93% rename from core-java-8/src/test/java/com/baeldung/java8/Java8DefaultStaticIntefaceMethodsTest.java rename to core-java/src/test/java/com/baeldung/java8/Java8DefaultStaticIntefaceMethodsUnitTest.java index 21a5e34b9b..5b07b3e3ae 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/Java8DefaultStaticIntefaceMethodsTest.java +++ b/core-java/src/test/java/com/baeldung/java8/Java8DefaultStaticIntefaceMethodsUnitTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; -public class Java8DefaultStaticIntefaceMethodsTest { +public class Java8DefaultStaticIntefaceMethodsUnitTest { @Test public void callStaticInterfaceMethdosMethods_whenExpectedResults_thenCorrect() { diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8ExecutorServiceTest.java b/core-java/src/test/java/com/baeldung/java8/Java8ExecutorServiceIntegrationTest.java similarity index 83% rename from core-java-8/src/test/java/com/baeldung/java8/Java8ExecutorServiceTest.java rename to core-java/src/test/java/com/baeldung/java8/Java8ExecutorServiceIntegrationTest.java index 581ccec182..41eb864fd9 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/Java8ExecutorServiceTest.java +++ b/core-java/src/test/java/com/baeldung/java8/Java8ExecutorServiceIntegrationTest.java @@ -1,17 +1,26 @@ package com.baeldung.java8; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import org.junit.Before; import org.junit.Test; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.*; - -import static org.junit.Assert.*; - - -public class Java8ExecutorServiceTest { +public class Java8ExecutorServiceIntegrationTest { private Runnable runnableTask; private Callable callableTask; @@ -53,9 +62,7 @@ public class Java8ExecutorServiceTest { @Test public void creationSubmittingTasksShuttingDownNow_whenShutDownAfterAwating_thenCorrect() { - ExecutorService threadPoolExecutor = - new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, - new LinkedBlockingQueue<>()); + ExecutorService threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); for (int i = 0; i < 100; i++) { threadPoolExecutor.submit(callableTask); @@ -138,8 +145,7 @@ public class Java8ExecutorServiceTest { @Test public void submittingTaskScheduling_whenExecuted_thenCorrect() { - ScheduledExecutorService executorService = Executors - .newSingleThreadScheduledExecutor(); + ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); Future resultFuture = executorService.schedule(callableTask, 1, TimeUnit.SECONDS); String result = null; diff --git a/core-java/src/test/java/com/baeldung/java8/Java8ForEachTest.java b/core-java/src/test/java/com/baeldung/java8/Java8ForEachTest.java new file mode 100644 index 0000000000..d9b0aa9d98 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java8/Java8ForEachTest.java @@ -0,0 +1,52 @@ +package com.baeldung.java8; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import org.junit.Test; + +public class Java8ForEachTest { + + @Test + public void compareForEachMethods_thenPrintResults() { + + List names = new ArrayList<>(); + names.add("Larry"); + names.add("Steve"); + names.add("James"); + names.add("Conan"); + names.add("Ellen"); + + // Java 5 - for-loop + System.out.println("--- Enhanced for-loop ---"); + for (String name : names) { + System.out.println(name); + } + + // Java 8 - forEach + System.out.println("--- forEach method ---"); + names.forEach(name -> System.out.println(name)); + + // Anonymous inner class that implements Consumer interface + System.out.println("--- Anonymous inner class ---"); + names.forEach(new Consumer() { + public void accept(String name) { + System.out.println(name); + } + }); + + // Create a Consumer implementation to then use in a forEach method + Consumer consumerNames = name -> { + System.out.println(name); + }; + System.out.println("--- Implementation of Consumer interface ---"); + names.forEach(consumerNames); + + // Print elements using a Method Reference + System.out.println("--- Method Reference ---"); + names.forEach(System.out::println); + + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8ForkJoinTest.java b/core-java/src/test/java/com/baeldung/java8/Java8ForkJoinIntegrationTest.java similarity index 94% rename from core-java-8/src/test/java/com/baeldung/java8/Java8ForkJoinTest.java rename to core-java/src/test/java/com/baeldung/java8/Java8ForkJoinIntegrationTest.java index 273b2d78db..6778fd782b 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/Java8ForkJoinTest.java +++ b/core-java/src/test/java/com/baeldung/java8/Java8ForkJoinIntegrationTest.java @@ -1,18 +1,20 @@ package com.baeldung.java8; - -import com.baeldung.forkjoin.CustomRecursiveAction; -import com.baeldung.forkjoin.CustomRecursiveTask; -import com.baeldung.forkjoin.util.PoolUtil; -import org.junit.Before; -import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.util.Random; import java.util.concurrent.ForkJoinPool; -import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; -public class Java8ForkJoinTest { +import com.baeldung.forkjoin.CustomRecursiveAction; +import com.baeldung.forkjoin.CustomRecursiveTask; +import com.baeldung.forkjoin.util.PoolUtil; + +public class Java8ForkJoinIntegrationTest { private int[] arr; private CustomRecursiveTask customRecursiveTask; @@ -27,28 +29,23 @@ public class Java8ForkJoinTest { customRecursiveTask = new CustomRecursiveTask(arr); } - @Test public void callPoolUtil_whenExistsAndExpectedType_thenCorrect() { - ForkJoinPool forkJoinPool = PoolUtil.forkJoinPool; ForkJoinPool forkJoinPoolTwo = PoolUtil.forkJoinPool; assertNotNull(forkJoinPool); assertEquals(2, forkJoinPool.getParallelism()); assertEquals(forkJoinPool, forkJoinPoolTwo); - } @Test public void callCommonPool_whenExistsAndExpectedType_thenCorrect() { - ForkJoinPool commonPool = ForkJoinPool.commonPool(); ForkJoinPool commonPoolTwo = ForkJoinPool.commonPool(); assertNotNull(commonPool); assertEquals(commonPool, commonPoolTwo); - } @Test @@ -63,7 +60,6 @@ public class Java8ForkJoinTest { @Test public void executeRecursiveTask_whenExecuted_thenCorrect() { - ForkJoinPool forkJoinPool = ForkJoinPool.commonPool(); forkJoinPool.execute(customRecursiveTask); @@ -73,12 +69,10 @@ public class Java8ForkJoinTest { forkJoinPool.submit(customRecursiveTask); int resultTwo = customRecursiveTask.join(); assertTrue(customRecursiveTask.isDone()); - } @Test public void executeRecursiveTaskWithFJ_whenExecuted_thenCorrect() { - CustomRecursiveTask customRecursiveTaskFirst = new CustomRecursiveTask(arr); CustomRecursiveTask customRecursiveTaskSecond = new CustomRecursiveTask(arr); CustomRecursiveTask customRecursiveTaskLast = new CustomRecursiveTask(arr); @@ -95,6 +89,6 @@ public class Java8ForkJoinTest { assertTrue(customRecursiveTaskSecond.isDone()); assertTrue(customRecursiveTaskLast.isDone()); assertTrue(result != 0); - } + } diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8FunctionalInteracesLambdasTest.java b/core-java/src/test/java/com/baeldung/java8/Java8FunctionalInteracesLambdasUnitTest.java similarity index 98% rename from core-java-8/src/test/java/com/baeldung/java8/Java8FunctionalInteracesLambdasTest.java rename to core-java/src/test/java/com/baeldung/java8/Java8FunctionalInteracesLambdasUnitTest.java index faaf3ae407..13ddcc805f 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/Java8FunctionalInteracesLambdasTest.java +++ b/core-java/src/test/java/com/baeldung/java8/Java8FunctionalInteracesLambdasUnitTest.java @@ -11,7 +11,7 @@ import java.util.function.Function; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -public class Java8FunctionalInteracesLambdasTest { +public class Java8FunctionalInteracesLambdasUnitTest { private UseFoo useFoo; diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8MethodReferenceTest.java b/core-java/src/test/java/com/baeldung/java8/Java8MethodReferenceUnitTest.java similarity index 97% rename from core-java-8/src/test/java/com/baeldung/java8/Java8MethodReferenceTest.java rename to core-java/src/test/java/com/baeldung/java8/Java8MethodReferenceUnitTest.java index d9d88c5052..2dc1fe18e6 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/Java8MethodReferenceTest.java +++ b/core-java/src/test/java/com/baeldung/java8/Java8MethodReferenceUnitTest.java @@ -12,7 +12,7 @@ import java.util.stream.Stream; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -public class Java8MethodReferenceTest { +public class Java8MethodReferenceUnitTest { private List list; diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8OptionalTest.java b/core-java/src/test/java/com/baeldung/java8/Java8OptionalUnitTest.java similarity index 80% rename from core-java-8/src/test/java/com/baeldung/java8/Java8OptionalTest.java rename to core-java/src/test/java/com/baeldung/java8/Java8OptionalUnitTest.java index 26de39bc0e..c6d5836387 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/Java8OptionalTest.java +++ b/core-java/src/test/java/com/baeldung/java8/Java8OptionalUnitTest.java @@ -1,16 +1,23 @@ package com.baeldung.java8; -import com.baeldung.java_8_features.*; -import org.junit.Before; -import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.List; import java.util.Optional; -import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; -public class Java8OptionalTest { +import com.baeldung.java_8_features.Address; +import com.baeldung.java_8_features.CustomException; +import com.baeldung.java_8_features.OptionalAddress; +import com.baeldung.java_8_features.OptionalUser; +import com.baeldung.java_8_features.User; + +public class Java8OptionalUnitTest { private List list; @@ -32,7 +39,6 @@ public class Java8OptionalTest { @Test public void checkOptional_whenAsExpected_thenCorrect() { - Optional optionalEmpty = Optional.empty(); assertFalse(optionalEmpty.isPresent()); @@ -52,27 +58,19 @@ public class Java8OptionalTest { assertTrue(listOptNull.isEmpty()); Optional user = Optional.ofNullable(getUser()); - String result = user.map(User::getAddress) - .map(Address::getStreet) - .orElse("not specified"); + String result = user.map(User::getAddress).map(Address::getStreet).orElse("not specified"); assertEquals(result, "1st Avenue"); Optional optionalUser = Optional.ofNullable(getOptionalUser()); - String resultOpt = optionalUser.flatMap(OptionalUser::getAddress) - .flatMap(OptionalAddress::getStreet) - .orElse("not specified"); + String resultOpt = optionalUser.flatMap(OptionalUser::getAddress).flatMap(OptionalAddress::getStreet).orElse("not specified"); assertEquals(resultOpt, "1st Avenue"); Optional userNull = Optional.ofNullable(getUserNull()); - String resultNull = userNull.map(User::getAddress) - .map(Address::getStreet) - .orElse("not specified"); + String resultNull = userNull.map(User::getAddress).map(Address::getStreet).orElse("not specified"); assertEquals(resultNull, "not specified"); Optional optionalUserNull = Optional.ofNullable(getOptionalUserNull()); - String resultOptNull = optionalUserNull.flatMap(OptionalUser::getAddress) - .flatMap(OptionalAddress::getStreet) - .orElse("not specified"); + String resultOptNull = optionalUserNull.flatMap(OptionalUser::getAddress).flatMap(OptionalAddress::getStreet).orElse("not specified"); assertEquals(resultOptNull, "not specified"); } diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8SortUnitTest.java b/core-java/src/test/java/com/baeldung/java8/Java8SortUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/java8/Java8SortUnitTest.java rename to core-java/src/test/java/com/baeldung/java8/Java8SortUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8StreamApiTest.java b/core-java/src/test/java/com/baeldung/java8/Java8StreamApiUnitTest.java similarity index 71% rename from core-java-8/src/test/java/com/baeldung/java8/Java8StreamApiTest.java rename to core-java/src/test/java/com/baeldung/java8/Java8StreamApiUnitTest.java index 37326c6d26..73a10a57f4 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/Java8StreamApiTest.java +++ b/core-java/src/test/java/com/baeldung/java8/Java8StreamApiUnitTest.java @@ -17,28 +17,24 @@ import java.util.stream.*; import static org.junit.Assert.*; -public class Java8StreamApiTest { +public class Java8StreamApiUnitTest { private long counter; - private static Logger log = LoggerFactory.getLogger(Java8StreamApiTest.class); + private static Logger log = LoggerFactory.getLogger(Java8StreamApiUnitTest.class); private List productList; @Before public void init() { - productList = Arrays.asList( - new Product(23, "potatoes"), new Product(14, "orange"), - new Product(13, "lemon"), new Product(23, "bread"), - new Product(13, "sugar")); + productList = Arrays.asList(new Product(23, "potatoes"), new Product(14, "orange"), new Product(13, "lemon"), new Product(23, "bread"), new Product(13, "sugar")); } @Test public void checkPipeline_whenStreamOneElementShorter_thenCorrect() { List list = Arrays.asList("abc1", "abc2", "abc3"); - long size = list.stream().skip(1) - .map(element -> element.substring(0, 3)).count(); + long size = list.stream().skip(1).map(element -> element.substring(0, 3)).count(); assertEquals(list.size() - 1, size); } @@ -48,11 +44,10 @@ public class Java8StreamApiTest { List list = Arrays.asList("abc1", "abc2", "abc3"); counter = 0; - long sizeFirst = list.stream() - .skip(2).map(element -> { - wasCalled(); - return element.substring(0, 3); - }).count(); + long sizeFirst = list.stream().skip(2).map(element -> { + wasCalled(); + return element.substring(0, 3); + }).count(); assertEquals(1, counter); counter = 0; @@ -84,7 +79,7 @@ public class Java8StreamApiTest { Stream streamOfArray = Stream.of("a", "b", "c"); assertEquals(3, streamOfArray.count()); - String[] arr = new String[]{"a", "b", "c"}; + String[] arr = new String[] { "a", "b", "c" }; Stream streamOfArrayPart = Arrays.stream(arr, 1, 3); assertEquals(2, streamOfArrayPart.count()); @@ -112,7 +107,7 @@ public class Java8StreamApiTest { } assertEquals("a", streamOfStrings.findFirst().get()); - Stream streamBuilder = Stream.builder().add("a").add("b").add("c").build(); + Stream streamBuilder = Stream. builder().add("a").add("b").add("c").build(); assertEquals(3, streamBuilder.count()); Stream streamGenerated = Stream.generate(() -> "element").limit(10); @@ -126,14 +121,13 @@ public class Java8StreamApiTest { public void runStreamPipeline_whenOrderIsRight_thenCorrect() { List list = Arrays.asList("abc1", "abc2", "abc3"); - Optional stream = list.stream() - .filter(element -> { - log.info("filter() was called"); - return element.contains("2"); - }).map(element -> { - log.info("map() was called"); - return element.toUpperCase(); - }).findFirst(); + Optional stream = list.stream().filter(element -> { + log.info("filter() was called"); + return element.contains("2"); + }).map(element -> { + log.info("map() was called"); + return element.toUpperCase(); + }).findFirst(); } @Test @@ -145,32 +139,28 @@ public class Java8StreamApiTest { int reducedTwoParams = IntStream.range(1, 4).reduce(10, (a, b) -> a + b); assertEquals(16, reducedTwoParams); - int reducedThreeParams = Stream.of(1, 2, 3) - .reduce(10, (a, b) -> a + b, (a, b) -> { - log.info("combiner was called"); - return a + b; - }); + int reducedThreeParams = Stream.of(1, 2, 3).reduce(10, (a, b) -> a + b, (a, b) -> { + log.info("combiner was called"); + return a + b; + }); assertEquals(16, reducedThreeParams); - int reducedThreeParamsParallel = Arrays.asList(1, 2, 3).parallelStream() - .reduce(10, (a, b) -> a + b, (a, b) -> { - log.info("combiner was called"); - return a + b; - }); + int reducedThreeParamsParallel = Arrays.asList(1, 2, 3).parallelStream().reduce(10, (a, b) -> a + b, (a, b) -> { + log.info("combiner was called"); + return a + b; + }); assertEquals(36, reducedThreeParamsParallel); } @Test public void collecting_whenAsExpected_thenCorrect() { - List collectorCollection = productList.stream() - .map(Product::getName).collect(Collectors.toList()); + List collectorCollection = productList.stream().map(Product::getName).collect(Collectors.toList()); assertTrue(collectorCollection instanceof List); assertEquals(5, collectorCollection.size()); - String listToString = productList.stream().map(Product::getName) - .collect(Collectors.joining(", ", "[", "]")); + String listToString = productList.stream().map(Product::getName).collect(Collectors.joining(", ", "[", "]")); assertTrue(listToString.contains(",") && listToString.contains("[") && listToString.contains("]")); @@ -180,36 +170,29 @@ public class Java8StreamApiTest { int summingPrice = productList.stream().collect(Collectors.summingInt(Product::getPrice)); assertEquals(86, summingPrice); - IntSummaryStatistics statistics = productList.stream() - .collect(Collectors.summarizingInt(Product::getPrice)); + IntSummaryStatistics statistics = productList.stream().collect(Collectors.summarizingInt(Product::getPrice)); assertEquals(23, statistics.getMax()); - Map> collectorMapOfLists = productList.stream() - .collect(Collectors.groupingBy(Product::getPrice)); + Map> collectorMapOfLists = productList.stream().collect(Collectors.groupingBy(Product::getPrice)); assertEquals(3, collectorMapOfLists.keySet().size()); - Map> mapPartioned = productList.stream() - .collect(Collectors.partitioningBy(element -> element.getPrice() > 15)); + Map> mapPartioned = productList.stream().collect(Collectors.partitioningBy(element -> element.getPrice() > 15)); assertEquals(2, mapPartioned.keySet().size()); } @Test(expected = UnsupportedOperationException.class) public void collect_whenThrows_thenCorrect() { - Set unmodifiableSet = productList.stream() - .collect(Collectors.collectingAndThen(Collectors.toSet(), - Collections::unmodifiableSet)); + Set unmodifiableSet = productList.stream().collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet)); unmodifiableSet.add(new Product(4, "tea")); } @Test public void customCollector_whenResultContainsAllElementsFrSource_thenCorrect() { - Collector> toLinkedList = - Collector.of(LinkedList::new, LinkedList::add, - (first, second) -> { - first.addAll(second); - return first; - }); + Collector> toLinkedList = Collector.of(LinkedList::new, LinkedList::add, (first, second) -> { + first.addAll(second); + return first; + }); LinkedList linkedListOfPersons = productList.stream().collect(toLinkedList); assertTrue(linkedListOfPersons.containsAll(productList)); @@ -219,23 +202,20 @@ public class Java8StreamApiTest { public void parallelStream_whenWorks_thenCorrect() { Stream streamOfCollection = productList.parallelStream(); boolean isParallel = streamOfCollection.isParallel(); - boolean haveBigPrice = streamOfCollection.map(product -> product.getPrice() * 12) - .anyMatch(price -> price > 200); + boolean haveBigPrice = streamOfCollection.map(product -> product.getPrice() * 12).anyMatch(price -> price > 200); assertTrue(isParallel && haveBigPrice); } @Test public void parallel_whenIsParallel_thenCorrect() { - IntStream intStreamParallel = - IntStream.range(1, 150).parallel().map(element -> element * 34); + IntStream intStreamParallel = IntStream.range(1, 150).parallel().map(element -> element * 34); boolean isParallel = intStreamParallel.isParallel(); assertTrue(isParallel); } @Test public void parallel_whenIsSequential_thenCorrect() { - IntStream intStreamParallel = - IntStream.range(1, 150).parallel().map(element -> element * 34); + IntStream intStreamParallel = IntStream.range(1, 150).parallel().map(element -> element * 34); IntStream intStreamSequential = intStreamParallel.sequential(); boolean isParallel = intStreamParallel.isParallel(); assertFalse(isParallel); diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8StreamsTest.java b/core-java/src/test/java/com/baeldung/java8/Java8StreamsUnitTest.java similarity index 87% rename from core-java-8/src/test/java/com/baeldung/java8/Java8StreamsTest.java rename to core-java/src/test/java/com/baeldung/java8/Java8StreamsUnitTest.java index 1f1dda49ce..e40f9f9506 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/Java8StreamsTest.java +++ b/core-java/src/test/java/com/baeldung/java8/Java8StreamsUnitTest.java @@ -14,7 +14,7 @@ import java.util.stream.Stream; import static org.junit.Assert.*; -public class Java8StreamsTest { +public class Java8StreamsUnitTest { private List list; @@ -36,7 +36,7 @@ public class Java8StreamsTest { @Test public void checkStreamCount_whenCreating_givenDifferentSources() { - String[] arr = new String[]{"a", "b", "c"}; + String[] arr = new String[] { "a", "b", "c" }; Stream streamArr = Arrays.stream(arr); assertEquals(streamArr.count(), 3); @@ -47,14 +47,12 @@ public class Java8StreamsTest { assertEquals(count, 9); } - @Test public void checkStreamCount_whenOperationFilter_thanCorrect() { Stream streamFilter = list.stream().filter(element -> element.isEmpty()); assertEquals(streamFilter.count(), 2); } - @Test public void checkStreamCount_whenOperationMap_thanCorrect() { List uris = new ArrayList<>(); @@ -65,12 +63,10 @@ public class Java8StreamsTest { List details = new ArrayList<>(); details.add(new Detail()); details.add(new Detail()); - Stream streamFlatMap = details.stream() - .flatMap(detail -> detail.getParts().stream()); + Stream streamFlatMap = details.stream().flatMap(detail -> detail.getParts().stream()); assertEquals(streamFlatMap.count(), 4); } - @Test public void checkStreamCount_whenOperationMatch_thenCorrect() { boolean isValid = list.stream().anyMatch(element -> element.contains("h")); @@ -81,7 +77,6 @@ public class Java8StreamsTest { assertFalse(isValidTwo); } - @Test public void checkStreamReducedValue_whenOperationReduce_thenCorrect() { List integers = new ArrayList<>(); @@ -94,20 +89,17 @@ public class Java8StreamsTest { @Test public void checkStreamContains_whenOperationCollect_thenCorrect() { - List resultList = list.stream() - .map(element -> element.toUpperCase()) - .collect(Collectors.toList()); + List resultList = list.stream().map(element -> element.toUpperCase()).collect(Collectors.toList()); assertEquals(resultList.size(), list.size()); assertTrue(resultList.contains("")); } - @Test public void checkParallelStream_whenDoWork() { list.parallelStream().forEach(element -> doWork(element)); } private void doWork(String string) { - assertTrue(true); //just imitate an amount of work + assertTrue(true); // just imitate an amount of work } } diff --git a/core-java-8/src/test/java/com/baeldung/java8/JavaFolderSizeTest.java b/core-java/src/test/java/com/baeldung/java8/JavaFolderSizeUnitTest.java similarity index 72% rename from core-java-8/src/test/java/com/baeldung/java8/JavaFolderSizeTest.java rename to core-java/src/test/java/com/baeldung/java8/JavaFolderSizeUnitTest.java index efd548a4b1..1f3b380772 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/JavaFolderSizeTest.java +++ b/core-java/src/test/java/com/baeldung/java8/JavaFolderSizeUnitTest.java @@ -1,43 +1,43 @@ package com.baeldung.java8; -import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Test; +import static org.junit.Assert.assertEquals; import java.io.File; import java.io.IOException; -import java.nio.file.*; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.text.DecimalFormat; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.StreamSupport; -import static org.junit.Assert.assertEquals; - -public class JavaFolderSizeTest { +import org.apache.commons.io.FileUtils; +import org.junit.Before; +import org.junit.Test; +public class JavaFolderSizeUnitTest { + private final long EXPECTED_SIZE = 24; private String path; @Before public void init() { final String separator = File.separator; - path = "src" + separator + "test" + separator + "resources"; + path = String.format("src%stest%sresources%stestFolder", separator, separator, separator); } @Test public void whenGetFolderSizeRecursive_thenCorrect() { - final long expectedSize = 136; - final File folder = new File(path); final long size = getFolderSize(folder); - assertEquals(expectedSize, size); + assertEquals(EXPECTED_SIZE, size); } @Test public void whenGetFolderSizeUsingJava7_thenCorrect() throws IOException { - final long expectedSize = 136; - final AtomicLong size = new AtomicLong(0); final Path folder = Paths.get(path); @@ -49,39 +49,33 @@ public class JavaFolderSizeTest { } }); - assertEquals(expectedSize, size.longValue()); + assertEquals(EXPECTED_SIZE, size.longValue()); } @Test public void whenGetFolderSizeUsingJava8_thenCorrect() throws IOException { - final long expectedSize = 136; - final Path folder = Paths.get(path); final long size = Files.walk(folder).filter(p -> p.toFile().isFile()).mapToLong(p -> p.toFile().length()).sum(); - assertEquals(expectedSize, size); + assertEquals(EXPECTED_SIZE, size); } @Test public void whenGetFolderSizeUsingApacheCommonsIO_thenCorrect() { - final long expectedSize = 136; - final File folder = new File(path); final long size = FileUtils.sizeOfDirectory(folder); - assertEquals(expectedSize, size); + assertEquals(EXPECTED_SIZE, size); } @Test public void whenGetFolderSizeUsingGuava_thenCorrect() { - final long expectedSize = 136; - final File folder = new File(path); final Iterable files = com.google.common.io.Files.fileTreeTraverser().breadthFirstTraversal(folder); - final long size = StreamSupport.stream(files.spliterator(), false).filter(f -> f.isFile()).mapToLong(File::length).sum(); + final long size = StreamSupport.stream(files.spliterator(), false).filter(File::isFile).mapToLong(File::length).sum(); - assertEquals(expectedSize, size); + assertEquals(EXPECTED_SIZE, size); } @Test @@ -89,25 +83,23 @@ public class JavaFolderSizeTest { final File folder = new File(path); final long size = getFolderSize(folder); - final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"}; + final String[] units = new String[] { "B", "KB", "MB", "GB", "TB" }; final int unitIndex = (int) (Math.log10(size) / 3); final double unitValue = 1 << (unitIndex * 10); final String readableSize = new DecimalFormat("#,##0.#").format(size / unitValue) + " " + units[unitIndex]; - assertEquals("136 B", readableSize); + assertEquals(EXPECTED_SIZE + " B", readableSize); } private long getFolderSize(final File folder) { long length = 0; final File[] files = folder.listFiles(); - final int count = files.length; - - for (int i = 0; i < count; i++) { - if (files[i].isFile()) { - length += files[i].length(); + for (final File file : files) { + if (file.isFile()) { + length += file.length(); } else { - length += getFolderSize(files[i]); + length += getFolderSize(file); } } return length; diff --git a/core-java-8/src/test/java/com/baeldung/java8/JavaTryWithResourcesTest.java b/core-java/src/test/java/com/baeldung/java8/JavaTryWithResourcesUnitTest.java similarity index 98% rename from core-java-8/src/test/java/com/baeldung/java8/JavaTryWithResourcesTest.java rename to core-java/src/test/java/com/baeldung/java8/JavaTryWithResourcesUnitTest.java index 224c4e9d6a..4c843ccaaf 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/JavaTryWithResourcesTest.java +++ b/core-java/src/test/java/com/baeldung/java8/JavaTryWithResourcesUnitTest.java @@ -8,7 +8,7 @@ import java.io.StringWriter; import java.util.Date; import java.util.Scanner; -public class JavaTryWithResourcesTest { +public class JavaTryWithResourcesUnitTest { private static final String TEST_STRING_HELLO_WORLD = "Hello World"; private Date resource1Date, resource2Date; diff --git a/core-java-8/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeTest.java b/core-java/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java similarity index 97% rename from core-java-8/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeTest.java rename to core-java/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java index 164a571817..7889e6ad53 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeTest.java +++ b/core-java/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java @@ -7,7 +7,7 @@ import java.io.UnsupportedEncodingException; import static org.junit.Assert.*; -public class ApacheCommonsEncodeDecodeTest { +public class ApacheCommonsEncodeDecodeUnitTest { // tests diff --git a/core-java-8/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeTest.java b/core-java/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java similarity index 98% rename from core-java-8/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeTest.java rename to core-java/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java index 18dccf71ba..62cfa4c0a1 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeTest.java +++ b/core-java/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java @@ -8,7 +8,7 @@ import java.util.UUID; import static org.junit.Assert.*; -public class Java8EncodeDecodeTest { +public class Java8EncodeDecodeUnitTest { // tests diff --git a/core-java-8/src/test/java/com/baeldung/java8/entity/Human.java b/core-java/src/test/java/com/baeldung/java8/entity/Human.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/java8/entity/Human.java rename to core-java/src/test/java/com/baeldung/java8/entity/Human.java diff --git a/core-java/src/test/java/com/baeldung/printscreen/ScreenshotIntegrationTest.java b/core-java/src/test/java/com/baeldung/printscreen/ScreenshotIntegrationTest.java new file mode 100644 index 0000000000..13609b6977 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/printscreen/ScreenshotIntegrationTest.java @@ -0,0 +1,25 @@ +package com.baeldung.printscreen; + +import org.junit.After; +import org.junit.Test; + +import java.io.File; + +import static org.junit.Assert.assertTrue; + +public class ScreenshotIntegrationTest { + + private Screenshot screenshot = new Screenshot("Screenshot.jpg"); + private File file = new File("Screenshot.jpg"); + + @Test + public void testGetScreenshot() throws Exception { + screenshot.getScreenshot(2000); + assertTrue(file.exists()); + } + + @After + public void tearDown() throws Exception { + file.delete(); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/socket/EchoIntegrationTest.java b/core-java/src/test/java/com/baeldung/socket/EchoIntegrationTest.java new file mode 100644 index 0000000000..7ac8e0a97a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/socket/EchoIntegrationTest.java @@ -0,0 +1,47 @@ +package com.baeldung.socket; + +import static org.junit.Assert.assertEquals; + +import java.util.concurrent.Executors; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class EchoIntegrationTest { + private static final Integer PORT = 4444; + + @BeforeClass + public static void start() throws InterruptedException { + Executors.newSingleThreadExecutor().submit(() -> new EchoServer().start(PORT)); + Thread.sleep(500); + } + + private EchoClient client = new EchoClient(); + + @Before + public void init() { + client.startConnection("127.0.0.1", PORT); + } + + @After + public void tearDown() { + client.stopConnection(); + } + + // + + @Test + public void givenClient_whenServerEchosMessage_thenCorrect() { + String resp1 = client.sendMessage("hello"); + String resp2 = client.sendMessage("world"); + String resp3 = client.sendMessage("!"); + String resp4 = client.sendMessage("."); + assertEquals("hello", resp1); + assertEquals("world", resp2); + assertEquals("!", resp3); + assertEquals("good bye", resp4); + } + +} diff --git a/core-java/src/test/java/com/baeldung/socket/GreetServerIntegrationTest.java b/core-java/src/test/java/com/baeldung/socket/GreetServerIntegrationTest.java new file mode 100644 index 0000000000..06b37d8539 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/socket/GreetServerIntegrationTest.java @@ -0,0 +1,41 @@ +package com.baeldung.socket; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.concurrent.Executors; + +import static org.junit.Assert.assertEquals; + +public class GreetServerIntegrationTest { + + private GreetClient client; + + private static final Integer PORT = 6666; + + @BeforeClass + public static void start() throws InterruptedException { + Executors.newSingleThreadExecutor().submit(() -> new GreetServer().start(PORT)); + Thread.sleep(500); + } + + @Before + public void init() { + client = new GreetClient(); + client.startConnection("127.0.0.1", PORT); + + } + + @Test + public void givenGreetingClient_whenServerRespondsWhenStarted_thenCorrect() { + String response = client.sendMessage("hello server"); + assertEquals("hello client", response); + } + + @After + public void finish() { + client.stopConnection(); + } +} diff --git a/core-java/src/test/java/com/baeldung/socket/SocketEchoMultiIntegrationTest.java b/core-java/src/test/java/com/baeldung/socket/SocketEchoMultiIntegrationTest.java new file mode 100644 index 0000000000..6ebc0946c5 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/socket/SocketEchoMultiIntegrationTest.java @@ -0,0 +1,59 @@ +package com.baeldung.socket; + +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.concurrent.Executors; + +import static org.junit.Assert.assertEquals; + +public class SocketEchoMultiIntegrationTest { + + private static final Integer PORT = 5555; + + @BeforeClass + public static void start() throws InterruptedException { + Executors.newSingleThreadExecutor().submit(() -> new EchoMultiServer().start(PORT)); + Thread.sleep(500); + } + + @Test + public void givenClient1_whenServerResponds_thenCorrect() { + EchoClient client = new EchoClient(); + client.startConnection("127.0.0.1", PORT); + String msg1 = client.sendMessage("hello"); + String msg2 = client.sendMessage("world"); + String terminate = client.sendMessage("."); + + assertEquals(msg1, "hello"); + assertEquals(msg2, "world"); + assertEquals(terminate, "bye"); + client.stopConnection(); + } + + @Test + public void givenClient2_whenServerResponds_thenCorrect() { + EchoClient client = new EchoClient(); + client.startConnection("127.0.0.1", PORT); + String msg1 = client.sendMessage("hello"); + String msg2 = client.sendMessage("world"); + String terminate = client.sendMessage("."); + assertEquals(msg1, "hello"); + assertEquals(msg2, "world"); + assertEquals(terminate, "bye"); + client.stopConnection(); + } + + @Test + public void givenClient3_whenServerResponds_thenCorrect() { + EchoClient client = new EchoClient(); + client.startConnection("127.0.0.1", PORT); + String msg1 = client.sendMessage("hello"); + String msg2 = client.sendMessage("world"); + String terminate = client.sendMessage("."); + assertEquals(msg1, "hello"); + assertEquals(msg2, "world"); + assertEquals(terminate, "bye"); + client.stopConnection(); + } +} diff --git a/core-java/src/test/java/com/baeldung/threadpool/CoreThreadPoolIntegrationTest.java b/core-java/src/test/java/com/baeldung/threadpool/CoreThreadPoolIntegrationTest.java new file mode 100644 index 0000000000..a62ec99043 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/threadpool/CoreThreadPoolIntegrationTest.java @@ -0,0 +1,153 @@ +package com.baeldung.threadpool; + +import static org.junit.Assert.assertEquals; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.Test; + +public class CoreThreadPoolIntegrationTest { + + @Test(timeout = 1000) + public void whenCallingExecuteWithRunnable_thenRunnableIsExecuted() throws InterruptedException { + + CountDownLatch lock = new CountDownLatch(1); + + Executor executor = Executors.newSingleThreadExecutor(); + executor.execute(() -> { + System.out.println("Hello World"); + lock.countDown(); + }); + + lock.await(1000, TimeUnit.MILLISECONDS); + } + + @Test + public void whenUsingExecutorServiceAndFuture_thenCanWaitOnFutureResult() throws InterruptedException, ExecutionException { + + ExecutorService executorService = Executors.newFixedThreadPool(10); + Future future = executorService.submit(() -> "Hello World"); + String result = future.get(); + + assertEquals("Hello World", result); + + } + + @Test + public void whenUsingFixedThreadPool_thenCoreAndMaximumThreadSizeAreTheSame() { + + ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2); + executor.submit(() -> { + Thread.sleep(1000); + return null; + }); + executor.submit(() -> { + Thread.sleep(1000); + return null; + }); + executor.submit(() -> { + Thread.sleep(1000); + return null; + }); + + assertEquals(2, executor.getPoolSize()); + assertEquals(1, executor.getQueue().size()); + + } + + @Test + public void whenUsingCachedThreadPool_thenPoolSizeGrowsUnbounded() { + ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); + executor.submit(() -> { + Thread.sleep(1000); + return null; + }); + executor.submit(() -> { + Thread.sleep(1000); + return null; + }); + executor.submit(() -> { + Thread.sleep(1000); + return null; + }); + + assertEquals(3, executor.getPoolSize()); + assertEquals(0, executor.getQueue().size()); + + } + + @Test(timeout = 1000) + public void whenUsingSingleThreadPool_thenTasksExecuteSequentially() throws InterruptedException { + + CountDownLatch lock = new CountDownLatch(2); + AtomicInteger counter = new AtomicInteger(); + + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.submit(() -> { + counter.set(1); + lock.countDown(); + }); + executor.submit(() -> { + counter.compareAndSet(1, 2); + lock.countDown(); + }); + + lock.await(1000, TimeUnit.MILLISECONDS); + assertEquals(2, counter.get()); + + } + + @Test(timeout = 1000) + public void whenSchedulingTask_thenTaskExecutesWithinGivenPeriod() throws InterruptedException { + + CountDownLatch lock = new CountDownLatch(1); + + ScheduledExecutorService executor = Executors.newScheduledThreadPool(5); + executor.schedule(() -> { + System.out.println("Hello World"); + lock.countDown(); + }, 500, TimeUnit.MILLISECONDS); + + lock.await(1000, TimeUnit.MILLISECONDS); + + } + + @Test(timeout = 1000) + public void whenSchedulingTaskWithFixedPeriod_thenTaskExecutesMultipleTimes() throws InterruptedException { + + CountDownLatch lock = new CountDownLatch(3); + + ScheduledExecutorService executor = Executors.newScheduledThreadPool(5); + ScheduledFuture future = executor.scheduleAtFixedRate(() -> { + System.out.println("Hello World"); + lock.countDown(); + }, 500, 100, TimeUnit.MILLISECONDS); + + lock.await(); + future.cancel(true); + + } + + @Test + public void whenUsingForkJoinPool_thenSumOfTreeElementsIsCalculatedCorrectly() { + + TreeNode tree = new TreeNode(5, new TreeNode(3), new TreeNode(2, new TreeNode(2), new TreeNode(8))); + + ForkJoinPool forkJoinPool = ForkJoinPool.commonPool(); + int sum = forkJoinPool.invoke(new CountingTask(tree)); + + assertEquals(20, sum); + } + +} diff --git a/core-java/src/test/java/com/baeldung/threadpool/GuavaThreadPoolIntegrationTest.java b/core-java/src/test/java/com/baeldung/threadpool/GuavaThreadPoolIntegrationTest.java new file mode 100644 index 0000000000..550e9dda6f --- /dev/null +++ b/core-java/src/test/java/com/baeldung/threadpool/GuavaThreadPoolIntegrationTest.java @@ -0,0 +1,54 @@ +package com.baeldung.threadpool; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class GuavaThreadPoolIntegrationTest { + + @Test + public void whenExecutingTaskWithDirectExecutor_thenTheTaskIsExecutedInTheCurrentThread() { + + Executor executor = MoreExecutors.directExecutor(); + + AtomicBoolean executed = new AtomicBoolean(); + + executor.execute(() -> { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + executed.set(true); + }); + + assertTrue(executed.get()); + } + + @Test + public void whenJoiningFuturesWithAllAsList_thenCombinedFutureCompletesAfterAllFuturesComplete() throws ExecutionException, InterruptedException { + + ExecutorService executorService = Executors.newCachedThreadPool(); + ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService); + + ListenableFuture future1 = listeningExecutorService.submit(() -> "Hello"); + ListenableFuture future2 = listeningExecutorService.submit(() -> "World"); + + String greeting = Futures.allAsList(future1, future2).get().stream().collect(Collectors.joining(" ")); + assertEquals("Hello World", greeting); + + } + +} diff --git a/core-java/src/test/java/com/baeldung/util/CurrentDateTimeUnitTest.java b/core-java/src/test/java/com/baeldung/util/CurrentDateTimeUnitTest.java new file mode 100644 index 0000000000..3ad3deb548 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/util/CurrentDateTimeUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.util; + +import static org.junit.Assert.assertEquals; + +import java.time.Clock; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.temporal.ChronoField; + +import org.junit.Test; + +public class CurrentDateTimeUnitTest { + + private static final Clock clock = Clock.fixed(Instant.parse("2016-10-09T15:10:30.00Z"), ZoneId.of("UTC")); + + @Test + public void shouldReturnCurrentDate() { + final LocalDate now = LocalDate.now(clock); + + assertEquals(9, now.get(ChronoField.DAY_OF_MONTH)); + assertEquals(10, now.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(2016, now.get(ChronoField.YEAR)); + } + + @Test + public void shouldReturnCurrentTime() { + final LocalTime now = LocalTime.now(clock); + + assertEquals(15, now.get(ChronoField.HOUR_OF_DAY)); + assertEquals(10, now.get(ChronoField.MINUTE_OF_HOUR)); + assertEquals(30, now.get(ChronoField.SECOND_OF_MINUTE)); + } + + @Test + public void shouldReturnCurrentTimestamp() { + final Instant now = Instant.now(clock); + + assertEquals(clock.instant().getEpochSecond(), now.getEpochSecond()); + } + +} diff --git a/core-java/src/test/java/org/baeldung/core/exceptions/FileNotFoundExceptionUnitTest.java b/core-java/src/test/java/org/baeldung/core/exceptions/FileNotFoundExceptionUnitTest.java new file mode 100644 index 0000000000..e615e6a7d1 --- /dev/null +++ b/core-java/src/test/java/org/baeldung/core/exceptions/FileNotFoundExceptionUnitTest.java @@ -0,0 +1,61 @@ +package org.baeldung.core.exceptions; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +import org.apache.log4j.Logger; +import org.junit.Test; + +public class FileNotFoundExceptionUnitTest { + + private static final Logger LOG = Logger.getLogger(FileNotFoundExceptionUnitTest.class); + + private String fileName = Double.toString(Math.random()); + + @Test(expected = BusinessException.class) + public void raiseBusinessSpecificException() throws IOException { + try { + readFailingFile(); + } catch (FileNotFoundException ex) { + throw new BusinessException("BusinessException: necessary file was not present.", ex); + } + } + + @Test + public void createFile() throws IOException { + try { + readFailingFile(); + } catch (FileNotFoundException ex) { + try { + new File(fileName).createNewFile(); + readFailingFile(); + } catch (IOException ioe) { + throw new RuntimeException("BusinessException: even creation is not possible.", ioe); + } + } + } + + @Test + public void logError() throws IOException { + try { + readFailingFile(); + } catch (FileNotFoundException ex) { + LOG.error("Optional file " + fileName + " was not found.", ex); + } + } + + private void readFailingFile() throws IOException { + BufferedReader rd = new BufferedReader(new FileReader(new File(fileName))); + rd.readLine(); + // no need to close file + } + + private class BusinessException extends RuntimeException { + BusinessException(String string, FileNotFoundException ex) { + super(string, ex); + } + } +} diff --git a/core-java/src/test/java/org/baeldung/equalshashcode/entities/ComplexClassUnitTest.java b/core-java/src/test/java/org/baeldung/equalshashcode/entities/ComplexClassUnitTest.java new file mode 100644 index 0000000000..680a6d57b5 --- /dev/null +++ b/core-java/src/test/java/org/baeldung/equalshashcode/entities/ComplexClassUnitTest.java @@ -0,0 +1,35 @@ +package org.baeldung.equalshashcode.entities; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import com.baeldung.equalshashcode.entities.ComplexClass; + +public class ComplexClassUnitTest { + + @Test + public void testEqualsAndHashcodes() { + List strArrayList = new ArrayList(); + strArrayList.add("abc"); + strArrayList.add("def"); + ComplexClass aObject = new ComplexClass(strArrayList, new HashSet(45, 67)); + ComplexClass bObject = new ComplexClass(strArrayList, new HashSet(45, 67)); + + List strArrayListD = new ArrayList(); + strArrayListD.add("lmn"); + strArrayListD.add("pqr"); + ComplexClass dObject = new ComplexClass(strArrayListD, new HashSet(45, 67)); + + Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject)); + + Assert.assertTrue(aObject.hashCode() == bObject.hashCode()); + + Assert.assertFalse(aObject.equals(dObject)); + Assert.assertFalse(aObject.hashCode() == dObject.hashCode()); + } + +} diff --git a/core-java/src/test/java/org/baeldung/equalshashcode/entities/PrimitiveClassUnitTest.java b/core-java/src/test/java/org/baeldung/equalshashcode/entities/PrimitiveClassUnitTest.java new file mode 100644 index 0000000000..f4e9f2b99f --- /dev/null +++ b/core-java/src/test/java/org/baeldung/equalshashcode/entities/PrimitiveClassUnitTest.java @@ -0,0 +1,25 @@ +package org.baeldung.equalshashcode.entities; + +import org.junit.Assert; +import org.junit.Test; + +import com.baeldung.equalshashcode.entities.PrimitiveClass; + +public class PrimitiveClassUnitTest { + + @Test + public void testTwoEqualsObjects() { + + PrimitiveClass aObject = new PrimitiveClass(false, 2); + PrimitiveClass bObject = new PrimitiveClass(false, 2); + PrimitiveClass dObject = new PrimitiveClass(true, 2); + + Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject)); + + Assert.assertTrue(aObject.hashCode() == bObject.hashCode()); + + Assert.assertFalse(aObject.equals(dObject)); + Assert.assertFalse(aObject.hashCode() == dObject.hashCode()); + } + +} diff --git a/core-java/src/test/java/org/baeldung/equalshashcode/entities/SquareClassUnitTest.java b/core-java/src/test/java/org/baeldung/equalshashcode/entities/SquareClassUnitTest.java new file mode 100644 index 0000000000..5c860bd62d --- /dev/null +++ b/core-java/src/test/java/org/baeldung/equalshashcode/entities/SquareClassUnitTest.java @@ -0,0 +1,27 @@ +package org.baeldung.equalshashcode.entities; + +import java.awt.Color; + +import org.junit.Assert; +import org.junit.Test; + +import com.baeldung.equalshashcode.entities.Square; + +public class SquareClassUnitTest { + + @Test + public void testEqualsAndHashcodes() { + Square aObject = new Square(10, Color.BLUE); + Square bObject = new Square(10, Color.BLUE); + + Square dObject = new Square(20, Color.BLUE); + + Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject)); + + Assert.assertTrue(aObject.hashCode() == bObject.hashCode()); + + Assert.assertFalse(aObject.equals(dObject)); + Assert.assertFalse(aObject.hashCode() == dObject.hashCode()); + } + +} diff --git a/core-java/src/test/java/org/baeldung/java/JavaIoIntegrationTest.java b/core-java/src/test/java/org/baeldung/java/JavaIoUnitTest.java similarity index 97% rename from core-java/src/test/java/org/baeldung/java/JavaIoIntegrationTest.java rename to core-java/src/test/java/org/baeldung/java/JavaIoUnitTest.java index ff92410bc4..3ab8e1de91 100644 --- a/core-java/src/test/java/org/baeldung/java/JavaIoIntegrationTest.java +++ b/core-java/src/test/java/org/baeldung/java/JavaIoUnitTest.java @@ -7,6 +7,7 @@ import java.util.Scanner; import org.apache.commons.io.FileUtils; import org.apache.commons.io.LineIterator; +import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,7 +15,8 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Charsets; import com.google.common.io.Files; -public class JavaIoIntegrationTest { +@Ignore("need large file for testing") +public class JavaIoUnitTest { protected final Logger logger = LoggerFactory.getLogger(getClass()); // tests - iterate lines in a file diff --git a/core-java/src/test/java/org/baeldung/java/JavaTimerUnitTest.java b/core-java/src/test/java/org/baeldung/java/JavaTimerLongRunningUnitTest.java similarity index 98% rename from core-java/src/test/java/org/baeldung/java/JavaTimerUnitTest.java rename to core-java/src/test/java/org/baeldung/java/JavaTimerLongRunningUnitTest.java index fcc74dbe64..3b126464ab 100644 --- a/core-java/src/test/java/org/baeldung/java/JavaTimerUnitTest.java +++ b/core-java/src/test/java/org/baeldung/java/JavaTimerLongRunningUnitTest.java @@ -9,7 +9,7 @@ import java.util.concurrent.TimeUnit; import org.junit.Test; -public class JavaTimerUnitTest { +public class JavaTimerLongRunningUnitTest { // tests @@ -90,7 +90,6 @@ public class JavaTimerUnitTest { @Override public void run() { System.out.println("Task performed on " + new Date()); - // TODO: stop the thread } }; final Timer timer = new Timer("Timer"); diff --git a/core-java/src/test/java/org/baeldung/java/arrays/ArraysJoinAndSplitJUnitTest.java b/core-java/src/test/java/org/baeldung/java/arrays/ArraysJoinAndSplitJUnitTest.java new file mode 100644 index 0000000000..885c3bcd6c --- /dev/null +++ b/core-java/src/test/java/org/baeldung/java/arrays/ArraysJoinAndSplitJUnitTest.java @@ -0,0 +1,41 @@ +package org.baeldung.java.arrays; + +import java.util.Arrays; + +import org.junit.Assert; +import org.junit.Test; + +public class ArraysJoinAndSplitJUnitTest { + + private final String[] sauces = { "Marinara", "Olive Oil" }; + private final String[] cheeses = { "Mozzarella", "Feta", "Parmesan" }; + private final String[] vegetables = { "Olives", "Spinach", "Green Peppers" }; + + private final String[] customers = { "Jay", "Harry", "Ronnie", "Gary", "Ross" }; + + @Test + public void givenThreeStringArrays_whenJoiningIntoOneStringArray_shouldSucceed() { + String[] toppings = new String[sauces.length + cheeses.length + vegetables.length]; + + System.arraycopy(sauces, 0, toppings, 0, sauces.length); + int AddedSoFar = sauces.length; + + System.arraycopy(cheeses, 0, toppings, AddedSoFar, cheeses.length); + AddedSoFar += cheeses.length; + + System.arraycopy(vegetables, 0, toppings, AddedSoFar, vegetables.length); + + Assert.assertArrayEquals(toppings, new String[] { "Marinara", "Olive Oil", "Mozzarella", "Feta", "Parmesan", "Olives", "Spinach", "Green Peppers" }); + } + + @Test + public void givenOneStringArray_whenSplittingInHalfTwoStringArrays_shouldSucceed() { + int ordersHalved = (customers.length / 2) + (customers.length % 2); + + String[] driverOne = Arrays.copyOf(customers, ordersHalved); + String[] driverTwo = Arrays.copyOfRange(customers, ordersHalved, customers.length); + + Assert.assertArrayEquals(driverOne, new String[] { "Jay", "Harry", "Ronnie" }); + Assert.assertArrayEquals(driverTwo, new String[] { "Gary", "Ross" }); + } +} diff --git a/core-java/src/test/java/org/baeldung/java/collections/ArrayListUnitTest.java b/core-java/src/test/java/org/baeldung/java/collections/ArrayListUnitTest.java new file mode 100644 index 0000000000..5d07628a96 --- /dev/null +++ b/core-java/src/test/java/org/baeldung/java/collections/ArrayListUnitTest.java @@ -0,0 +1,137 @@ +package org.baeldung.java.collections; + +import com.google.common.collect.Sets; +import org.junit.Before; +import org.junit.Test; + +import java.util.*; +import java.util.stream.*; + +import static java.util.stream.Collectors.*; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.core.IsNot.not; +import static org.junit.Assert.*; + +public class ArrayListUnitTest { + + private List stringsToSearch; + + @Before + public void setUp() { + List list = LongStream.range(0, 16).boxed().map(Long::toHexString).collect(toCollection(ArrayList::new)); + stringsToSearch = new ArrayList<>(list); + stringsToSearch.addAll(list); + } + + @Test + public void givenNewArrayList_whenCheckCapacity_thenDefaultValue() { + List list = new ArrayList<>(); + assertTrue(list.isEmpty()); + } + + @Test + public void givenCollection_whenProvideItToArrayListCtor_thenArrayListIsPopulatedWithItsElements() { + Collection numbers = IntStream.range(0, 10).boxed().collect(toSet()); + + List list = new ArrayList<>(numbers); + assertEquals(10, list.size()); + assertTrue(numbers.containsAll(list)); + } + + @Test + public void givenElement_whenAddToArrayList_thenIsAdded() { + List list = new ArrayList<>(); + + list.add(1L); + list.add(2L); + list.add(1, 3L); + + assertThat(Arrays.asList(1L, 3L, 2L), equalTo(list)); + } + + @Test + public void givenCollection_whenAddToArrayList_thenIsAdded() { + List list = new ArrayList<>(Arrays.asList(1L, 2L, 3L)); + LongStream.range(4, 10).boxed().collect(collectingAndThen(toCollection(ArrayList::new), ys -> list.addAll(0, ys))); + + assertThat(Arrays.asList(4L, 5L, 6L, 7L, 8L, 9L, 1L, 2L, 3L), equalTo(list)); + } + + @Test + public void givenExistingElement_whenCallIndexOf_thenReturnCorrectIndex() { + assertEquals(10, stringsToSearch.indexOf("a")); + assertEquals(26, stringsToSearch.lastIndexOf("a")); + } + + @Test + public void givenCondition_whenIterateArrayList_thenFindAllElementsSatisfyingCondition() { + Iterator it = stringsToSearch.iterator(); + Set matchingStrings = new HashSet<>(Arrays.asList("a", "c", "9")); + + List result = new ArrayList<>(); + while (it.hasNext()) { + String s = it.next(); + if (matchingStrings.contains(s)) { + result.add(s); + } + } + + assertEquals(6, result.size()); + } + + @Test + public void givenPredicate_whenIterateArrayList_thenFindAllElementsSatisfyingPredicate() { + Set matchingStrings = new HashSet<>(Arrays.asList("a", "c", "9")); + + List result = stringsToSearch.stream().filter(matchingStrings::contains).collect(toCollection(ArrayList::new)); + + assertEquals(6, result.size()); + } + + @Test + public void givenSortedArray_whenUseBinarySearch_thenFindElement() { + List copy = new ArrayList<>(stringsToSearch); + Collections.sort(copy); + int index = Collections.binarySearch(copy, "f"); + assertThat(index, not(equalTo(-1))); + } + + @Test + public void givenIndex_whenRemove_thenCorrectElementRemoved() { + List list = IntStream.range(0, 10).boxed().collect(toCollection(ArrayList::new)); + Collections.reverse(list); + + list.remove(0); + assertThat(list.get(0), equalTo(8)); + + list.remove(Integer.valueOf(0)); + assertFalse(list.contains(0)); + } + + @Test + public void givenListIterator_whenReverseTraversal_thenRetrieveElementsInOppositeOrder() { + List list = IntStream.range(0, 10).boxed().collect(toCollection(ArrayList::new)); + ListIterator it = list.listIterator(list.size()); + List result = new ArrayList<>(list.size()); + while (it.hasPrevious()) { + result.add(it.previous()); + } + + Collections.reverse(list); + assertThat(result, equalTo(list)); + } + + @Test + public void givenCondition_whenIterateArrayList_thenRemoveAllElementsSatisfyingCondition() { + Set matchingStrings = Sets.newHashSet("a", "b", "c", "d", "e", "f"); + + Iterator it = stringsToSearch.iterator(); + while (it.hasNext()) { + if (matchingStrings.contains(it.next())) { + it.remove(); + } + } + + assertEquals(20, stringsToSearch.size()); + } +} diff --git a/core-java/src/test/java/org/baeldung/java/collections/CollectionsJoinAndSplitJUnitTest.java b/core-java/src/test/java/org/baeldung/java/collections/CollectionsJoinAndSplitJUnitTest.java new file mode 100644 index 0000000000..c288cf499d --- /dev/null +++ b/core-java/src/test/java/org/baeldung/java/collections/CollectionsJoinAndSplitJUnitTest.java @@ -0,0 +1,62 @@ +package org.baeldung.java.collections; + +import java.util.ArrayList; +import java.util.Collections; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class CollectionsJoinAndSplitJUnitTest { + + private ArrayList sauces = new ArrayList<>(); + private ArrayList cheeses = new ArrayList<>(); + private ArrayList vegetables = new ArrayList<>(); + + private ArrayList> ingredients = new ArrayList<>(); + + @Before + public void init() { + sauces.add("Olive Oil"); + sauces.add("Marinara"); + + cheeses.add("Mozzarella"); + cheeses.add("Feta"); + cheeses.add("Parmesan"); + + vegetables.add("Olives"); + vegetables.add("Spinach"); + vegetables.add("Green Peppers"); + + ingredients.add(sauces); + ingredients.add(cheeses); + ingredients.add(vegetables); + } + + @Test + public void givenThreeArrayLists_whenJoiningIntoOneArrayList_shouldSucceed() { + ArrayList> toppings = new ArrayList<>(); + + toppings.add(sauces); + toppings.add(cheeses); + toppings.add(vegetables); + + Assert.assertTrue(toppings.size() == 3); + Assert.assertTrue(toppings.contains(sauces)); + Assert.assertTrue(toppings.contains(cheeses)); + Assert.assertTrue(toppings.contains(vegetables)); + } + + @Test + public void givenOneArrayList_whenSplittingIntoTwoArrayLists_shouldSucceed() { + + ArrayList> removedToppings = new ArrayList<>(); + removedToppings.add(ingredients.remove(ingredients.indexOf(vegetables))); + + Assert.assertTrue(removedToppings.contains(vegetables)); + Assert.assertTrue(removedToppings.size() == 1); + Assert.assertTrue(ingredients.size() == 2); + Assert.assertTrue(ingredients.contains(sauces)); + Assert.assertTrue(ingredients.contains(cheeses)); + } +} diff --git a/core-java/src/test/java/org/baeldung/java/enums/PizzaTest.java b/core-java/src/test/java/org/baeldung/java/enums/PizzaUnitTest.java similarity index 60% rename from core-java/src/test/java/org/baeldung/java/enums/PizzaTest.java rename to core-java/src/test/java/org/baeldung/java/enums/PizzaUnitTest.java index a6814ee600..bb3abff28d 100644 --- a/core-java/src/test/java/org/baeldung/java/enums/PizzaTest.java +++ b/core-java/src/test/java/org/baeldung/java/enums/PizzaUnitTest.java @@ -1,21 +1,21 @@ package org.baeldung.java.enums; - -import com.baeldung.enums.Pizza; -import org.junit.Test; +import static junit.framework.TestCase.assertTrue; import java.util.ArrayList; import java.util.EnumMap; import java.util.List; -import static junit.framework.TestCase.assertTrue; +import org.junit.Test; +import com.baeldung.enums.Pizza; + +public class PizzaUnitTest { -public class PizzaTest { @Test public void givenPizaOrder_whenReady_thenDeliverable() { Pizza testPz = new Pizza(); - testPz.setStatus(Pizza.PizzaStatus.READY); + testPz.setStatus(Pizza.PizzaStatusEnum.READY); assertTrue(testPz.isDeliverable()); } @@ -23,16 +23,16 @@ public class PizzaTest { public void givenPizaOrders_whenRetrievingUnDeliveredPzs_thenCorrectlyRetrieved() { List pzList = new ArrayList<>(); Pizza pz1 = new Pizza(); - pz1.setStatus(Pizza.PizzaStatus.DELIVERED); + pz1.setStatus(Pizza.PizzaStatusEnum.DELIVERED); Pizza pz2 = new Pizza(); - pz2.setStatus(Pizza.PizzaStatus.ORDERED); + pz2.setStatus(Pizza.PizzaStatusEnum.ORDERED); Pizza pz3 = new Pizza(); - pz3.setStatus(Pizza.PizzaStatus.ORDERED); + pz3.setStatus(Pizza.PizzaStatusEnum.ORDERED); Pizza pz4 = new Pizza(); - pz4.setStatus(Pizza.PizzaStatus.READY); + pz4.setStatus(Pizza.PizzaStatusEnum.READY); pzList.add(pz1); pzList.add(pz2); @@ -48,33 +48,34 @@ public class PizzaTest { List pzList = new ArrayList<>(); Pizza pz1 = new Pizza(); - pz1.setStatus(Pizza.PizzaStatus.DELIVERED); + pz1.setStatus(Pizza.PizzaStatusEnum.DELIVERED); Pizza pz2 = new Pizza(); - pz2.setStatus(Pizza.PizzaStatus.ORDERED); + pz2.setStatus(Pizza.PizzaStatusEnum.ORDERED); Pizza pz3 = new Pizza(); - pz3.setStatus(Pizza.PizzaStatus.ORDERED); + pz3.setStatus(Pizza.PizzaStatusEnum.ORDERED); Pizza pz4 = new Pizza(); - pz4.setStatus(Pizza.PizzaStatus.READY); + pz4.setStatus(Pizza.PizzaStatusEnum.READY); pzList.add(pz1); pzList.add(pz2); pzList.add(pz3); pzList.add(pz4); - EnumMap> map = Pizza.groupPizzaByStatus(pzList); - assertTrue(map.get(Pizza.PizzaStatus.DELIVERED).size() == 1); - assertTrue(map.get(Pizza.PizzaStatus.ORDERED).size() == 2); - assertTrue(map.get(Pizza.PizzaStatus.READY).size() == 1); + EnumMap> map = Pizza.groupPizzaByStatus(pzList); + assertTrue(map.get(Pizza.PizzaStatusEnum.DELIVERED).size() == 1); + assertTrue(map.get(Pizza.PizzaStatusEnum.ORDERED).size() == 2); + assertTrue(map.get(Pizza.PizzaStatusEnum.READY).size() == 1); } @Test public void givenPizaOrder_whenDelivered_thenPizzaGetsDeliveredAndStatusChanges() { Pizza pz = new Pizza(); - pz.setStatus(Pizza.PizzaStatus.READY); + pz.setStatus(Pizza.PizzaStatusEnum.READY); pz.deliver(); - assertTrue(pz.getStatus() == Pizza.PizzaStatus.DELIVERED); + assertTrue(pz.getStatus() == Pizza.PizzaStatusEnum.DELIVERED); } + } diff --git a/core-java/src/test/java/org/baeldung/java/io/JavaFileIntegrationTest.java b/core-java/src/test/java/org/baeldung/java/io/JavaFileUnitTest.java similarity index 86% rename from core-java/src/test/java/org/baeldung/java/io/JavaFileIntegrationTest.java rename to core-java/src/test/java/org/baeldung/java/io/JavaFileUnitTest.java index 24213ba869..4b56a97325 100644 --- a/core-java/src/test/java/org/baeldung/java/io/JavaFileIntegrationTest.java +++ b/core-java/src/test/java/org/baeldung/java/io/JavaFileUnitTest.java @@ -13,7 +13,7 @@ import java.nio.file.Paths; import org.apache.commons.io.FileUtils; import org.junit.Test; -public class JavaFileIntegrationTest { +public class JavaFileUnitTest { // create a file @@ -46,7 +46,7 @@ public class JavaFileIntegrationTest { @Test public final void givenUsingJDK6_whenMovingFile_thenCorrect() throws IOException { final File fileToMove = new File("src/test/resources/toMoveFile_jdk6.txt"); - fileToMove.exists(); + fileToMove.createNewFile();// .exists(); final File destDir = new File("src/test/resources/"); destDir.mkdir(); @@ -68,7 +68,7 @@ public class JavaFileIntegrationTest { public final void givenUsingGuava_whenMovingFile_thenCorrect() throws IOException { final File fileToMove = new File("src/test/resources/fileToMove.txt"); fileToMove.createNewFile(); - final File destDir = new File("src/test/resources/"); + final File destDir = new File("src/main/resources/"); final File targetFile = new File(destDir, fileToMove.getName()); com.google.common.io.Files.createParentDirs(targetFile); com.google.common.io.Files.move(fileToMove, targetFile); @@ -76,13 +76,14 @@ public class JavaFileIntegrationTest { @Test public final void givenUsingApache_whenMovingFile_thenCorrect() throws IOException { - FileUtils.moveFile(FileUtils.getFile("src/test/resources/fileToMove.txt"), FileUtils.getFile("src/test/resources/fileMoved.txt")); + FileUtils.touch(new File("src/test/resources/fileToMove_apache.txt")); + FileUtils.moveFile(FileUtils.getFile("src/test/resources/fileToMove_apache.txt"), FileUtils.getFile("src/test/resources/fileMoved_apache2.txt")); } @Test public final void givenUsingApache_whenMovingFileApproach2_thenCorrect() throws IOException { - FileUtils.touch(new File("src/test/resources/fileToMove.txt")); - FileUtils.moveFileToDirectory(FileUtils.getFile("src/test/resources/fileToMove.txt"), FileUtils.getFile("src/main/resources/"), true); + FileUtils.touch(new File("src/test/resources/fileToMove_apache.txt")); + FileUtils.moveFileToDirectory(FileUtils.getFile("src/test/resources/fileToMove_apache.txt"), FileUtils.getFile("src/main/resources/"), true); } // delete a file @@ -99,7 +100,7 @@ public class JavaFileIntegrationTest { @Test public final void givenUsingJDK7nio2_whenDeletingAFile_thenCorrect() throws IOException { - // Files.createFile(Paths.get("src/test/resources/fileToDelete_jdk7.txt")); + Files.createFile(Paths.get("src/test/resources/fileToDelete_jdk7.txt")); final Path fileToDeletePath = Paths.get("src/test/resources/fileToDelete_jdk7.txt"); Files.delete(fileToDeletePath); @@ -117,7 +118,7 @@ public class JavaFileIntegrationTest { @Test public void givenUsingCommonsIo_whenDeletingAFileV2_thenCorrect() throws IOException { - // FileUtils.touch(new File("src/test/resources/fileToDelete.txt")); + FileUtils.touch(new File("src/test/resources/fileToDelete.txt")); FileUtils.forceDelete(FileUtils.getFile("src/test/resources/fileToDelete.txt")); } diff --git a/core-java/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java b/core-java/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java index 55a0904499..1a6ac5f8ce 100644 --- a/core-java/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java +++ b/core-java/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java @@ -19,6 +19,7 @@ import java.io.Reader; import java.io.StringWriter; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.nio.file.StandardCopyOption; import java.util.Scanner; import org.apache.commons.io.FileUtils; @@ -191,6 +192,16 @@ public class JavaInputStreamToXUnitTest { IOUtils.closeQuietly(outStream); } + @Test + public final void givenUsingPlainJava8_whenConvertingAnInProgressInputStreamToAFile_thenCorrect() throws IOException { + final InputStream initialStream = new FileInputStream(new File("src/main/resources/sample.txt")); + final File targetFile = new File("src/main/resources/targetFile.tmp"); + + java.nio.file.Files.copy(initialStream, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + + IOUtils.closeQuietly(initialStream); + } + @Test public final void givenUsingGuava_whenConvertingAnInputStreamToAFile_thenCorrect() throws IOException { final InputStream initialStream = new FileInputStream(new File("src/main/resources/sample.txt")); diff --git a/core-java/src/test/java/org/baeldung/java/io/JavaReadFromFileTest.java b/core-java/src/test/java/org/baeldung/java/io/JavaReadFromFileUnitTest.java similarity index 97% rename from core-java/src/test/java/org/baeldung/java/io/JavaReadFromFileTest.java rename to core-java/src/test/java/org/baeldung/java/io/JavaReadFromFileUnitTest.java index e679b82d3f..b1aa58424d 100644 --- a/core-java/src/test/java/org/baeldung/java/io/JavaReadFromFileTest.java +++ b/core-java/src/test/java/org/baeldung/java/io/JavaReadFromFileUnitTest.java @@ -23,7 +23,7 @@ import java.util.Scanner; import org.junit.Test; -public class JavaReadFromFileTest { +public class JavaReadFromFileUnitTest { @Test public void whenReadWithBufferedReader_thenCorrect() throws IOException { @@ -115,7 +115,7 @@ public class JavaReadFromFileTest { final BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("src/test/resources/test_read7.in"), "UTF-8")); final String currentLine = reader.readLine(); reader.close(); - + System.out.println(currentLine); assertEquals(expected_value, currentLine); } @@ -143,8 +143,9 @@ public class JavaReadFromFileTest { final FileChannel channel = reader.getChannel(); int bufferSize = 1024; - if (bufferSize > channel.size()) + if (bufferSize > channel.size()) { bufferSize = (int) channel.size(); + } final ByteBuffer buff = ByteBuffer.allocate(bufferSize); channel.read(buff); buff.flip(); diff --git a/core-java/src/test/java/org/baeldung/java/io/JavaReaderToXUnitTest.java b/core-java/src/test/java/org/baeldung/java/io/JavaReaderToXUnitTest.java index 7a4c7366eb..3c574f1e5c 100644 --- a/core-java/src/test/java/org/baeldung/java/io/JavaReaderToXUnitTest.java +++ b/core-java/src/test/java/org/baeldung/java/io/JavaReaderToXUnitTest.java @@ -1,5 +1,8 @@ package org.baeldung.java.io; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileWriter; @@ -187,10 +190,24 @@ public class JavaReaderToXUnitTest { targetStream.close(); } + @Test + public void givenUsingCommonsIO_whenConvertingReaderIntoInputStream_thenCorrect() throws IOException { + String initialString = "With Commons IO"; + final Reader initialReader = new StringReader(initialString); + + final InputStream targetStream = IOUtils.toInputStream(IOUtils.toString(initialReader)); + + final String finalString = IOUtils.toString(targetStream); + assertThat(finalString, equalTo(initialString)); + + initialReader.close(); + targetStream.close(); + } + // tests - Reader to InputStream with encoding @Test - public void givenUsingPlainJava_whenConvertingReaderIntoInputStreamWithCharset_thenCorrect() throws IOException { + public void givenUsingPlainJava_whenConvertingReaderIntoInputStreamWithCharset() throws IOException { final Reader initialReader = new StringReader("With Java"); final char[] charBuffer = new char[8 * 1024]; @@ -225,4 +242,17 @@ public class JavaReaderToXUnitTest { targetStream.close(); } + @Test + public void givenUsingCommonsIO_whenConvertingReaderIntoInputStreamWithEncoding_thenCorrect() throws IOException { + String initialString = "With Commons IO"; + final Reader initialReader = new StringReader(initialString); + final InputStream targetStream = IOUtils.toInputStream(IOUtils.toString(initialReader), Charsets.UTF_8); + + String finalString = IOUtils.toString(targetStream, Charsets.UTF_8); + assertThat(finalString, equalTo(initialString)); + + initialReader.close(); + targetStream.close(); + } + } diff --git a/core-java/src/test/java/org/baeldung/java/io/JavaScannerTest.java b/core-java/src/test/java/org/baeldung/java/io/JavaScannerUnitTest.java similarity index 99% rename from core-java/src/test/java/org/baeldung/java/io/JavaScannerTest.java rename to core-java/src/test/java/org/baeldung/java/io/JavaScannerUnitTest.java index 61f0f52316..5af286dbca 100644 --- a/core-java/src/test/java/org/baeldung/java/io/JavaScannerTest.java +++ b/core-java/src/test/java/org/baeldung/java/io/JavaScannerUnitTest.java @@ -15,7 +15,7 @@ import java.util.Scanner; import org.junit.Test; -public class JavaScannerTest { +public class JavaScannerUnitTest { @Test public void whenReadFileWithScanner_thenCorrect() throws IOException { diff --git a/core-java/src/test/java/org/baeldung/java/io/JavaWriteToFileTest.java b/core-java/src/test/java/org/baeldung/java/io/JavaWriteToFileUnitTest.java similarity index 99% rename from core-java/src/test/java/org/baeldung/java/io/JavaWriteToFileTest.java rename to core-java/src/test/java/org/baeldung/java/io/JavaWriteToFileUnitTest.java index 93cfffa39d..9ff95c4e16 100644 --- a/core-java/src/test/java/org/baeldung/java/io/JavaWriteToFileTest.java +++ b/core-java/src/test/java/org/baeldung/java/io/JavaWriteToFileUnitTest.java @@ -26,7 +26,7 @@ import java.nio.file.Paths; import org.junit.Test; -public class JavaWriteToFileTest { +public class JavaWriteToFileUnitTest { private String fileName = "src/test/resources/test_write.txt"; private String fileName1 = "src/test/resources/test_write_1.txt"; diff --git a/core-java/src/test/java/org/baeldung/java/lists/ListAssertJTest.java b/core-java/src/test/java/org/baeldung/java/lists/ListAssertJUnitTest.java similarity index 83% rename from core-java/src/test/java/org/baeldung/java/lists/ListAssertJTest.java rename to core-java/src/test/java/org/baeldung/java/lists/ListAssertJUnitTest.java index b8926946a9..c609f5badb 100644 --- a/core-java/src/test/java/org/baeldung/java/lists/ListAssertJTest.java +++ b/core-java/src/test/java/org/baeldung/java/lists/ListAssertJUnitTest.java @@ -7,7 +7,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -public class ListAssertJTest { +public class ListAssertJUnitTest { private final List list1 = Arrays.asList("1", "2", "3", "4"); private final List list2 = Arrays.asList("1", "2", "3", "4"); @@ -15,9 +15,7 @@ public class ListAssertJTest { @Test public void whenTestingForEquality_ShouldBeEqual() throws Exception { - assertThat(list1) - .isEqualTo(list2) - .isNotEqualTo(list3); + assertThat(list1).isEqualTo(list2).isNotEqualTo(list3); assertThat(list1.equals(list2)).isTrue(); assertThat(list1.equals(list3)).isFalse(); diff --git a/core-java/src/test/java/org/baeldung/java/lists/ListTestNGTest.java b/core-java/src/test/java/org/baeldung/java/lists/ListTestNgUnitTest.java similarity index 94% rename from core-java/src/test/java/org/baeldung/java/lists/ListTestNGTest.java rename to core-java/src/test/java/org/baeldung/java/lists/ListTestNgUnitTest.java index fa80d0e224..b7c2bd7272 100644 --- a/core-java/src/test/java/org/baeldung/java/lists/ListTestNGTest.java +++ b/core-java/src/test/java/org/baeldung/java/lists/ListTestNgUnitTest.java @@ -6,7 +6,7 @@ import org.testng.annotations.Test; import java.util.Arrays; import java.util.List; -public class ListTestNGTest { +public class ListTestNgUnitTest { private final List list1 = Arrays.asList("1", "2", "3", "4"); private final List list2 = Arrays.asList("1", "2", "3", "4"); diff --git a/core-java/src/test/java/org/baeldung/java/lists/README.md b/core-java/src/test/java/org/baeldung/java/lists/README.md new file mode 100644 index 0000000000..2a1e8aeeaa --- /dev/null +++ b/core-java/src/test/java/org/baeldung/java/lists/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Check If Two Lists are Equal in Java](http://www.baeldung.com/java-test-a-list-for-ordinality-and-equality) diff --git a/core-java/src/test/java/org/baeldung/java/md5/JavaMD5UnitTest.java b/core-java/src/test/java/org/baeldung/java/md5/JavaMD5UnitTest.java new file mode 100644 index 0000000000..55e71470c8 --- /dev/null +++ b/core-java/src/test/java/org/baeldung/java/md5/JavaMD5UnitTest.java @@ -0,0 +1,75 @@ +package org.baeldung.java.md5; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import javax.xml.bind.DatatypeConverter; + +import org.apache.commons.codec.digest.DigestUtils; +import org.junit.Test; + +import com.google.common.hash.HashCode; +import com.google.common.hash.Hashing; + +public class JavaMD5UnitTest { + + String filename = "src/test/resources/test_md5.txt"; + String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3"; + + String hash = "35454B055CC325EA1AF2126E27707052"; + String password = "ILoveJava"; + + @Test + public void givenPassword_whenHashing_thenVerifying() throws NoSuchAlgorithmException { + String hash = "35454B055CC325EA1AF2126E27707052"; + String password = "ILoveJava"; + + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(password.getBytes()); + byte[] digest = md.digest(); + String myHash = DatatypeConverter.printHexBinary(digest).toUpperCase(); + + assertThat(myHash.equals(hash)).isTrue(); + } + + @Test + public void givenFile_generatingChecksum_thenVerifying() throws NoSuchAlgorithmException, IOException { + String filename = "src/test/resources/test_md5.txt"; + String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3"; + + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(Files.readAllBytes(Paths.get(filename))); + byte[] digest = md.digest(); + String myChecksum = DatatypeConverter.printHexBinary(digest).toUpperCase(); + + assertThat(myChecksum.equals(checksum)).isTrue(); + } + + @Test + public void givenPassword_whenHashingUsingCommons_thenVerifying() { + String hash = "35454B055CC325EA1AF2126E27707052"; + String password = "ILoveJava"; + + String md5Hex = DigestUtils.md5Hex(password).toUpperCase(); + + assertThat(md5Hex.equals(hash)).isTrue(); + } + + @Test + public void givenFile_whenChecksumUsingGuava_thenVerifying() throws IOException { + String filename = "src/test/resources/test_md5.txt"; + String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3"; + + HashCode hash = com.google.common.io.Files.hash(new File(filename), Hashing.md5()); + String myChecksum = hash.toString().toUpperCase(); + + assertThat(myChecksum.equals(checksum)).isTrue(); + } + +} diff --git a/core-java/src/test/java/org/baeldung/java/sandbox/SandboxJavaTest.java b/core-java/src/test/java/org/baeldung/java/sandbox/SandboxJavaManualTest.java similarity index 98% rename from core-java/src/test/java/org/baeldung/java/sandbox/SandboxJavaTest.java rename to core-java/src/test/java/org/baeldung/java/sandbox/SandboxJavaManualTest.java index 5127ccb10c..bb849d6a13 100644 --- a/core-java/src/test/java/org/baeldung/java/sandbox/SandboxJavaTest.java +++ b/core-java/src/test/java/org/baeldung/java/sandbox/SandboxJavaManualTest.java @@ -6,7 +6,7 @@ import java.util.TimerTask; import org.junit.Test; -public class SandboxJavaTest { +public class SandboxJavaManualTest { @Test public void givenUsingTimer_whenSchedulingTimerTaskOnce_thenCorrect() throws InterruptedException { diff --git a/core-java/src/test/java/org/baeldung/java/shell/JavaProcessUnitTest.java b/core-java/src/test/java/org/baeldung/java/shell/JavaProcessUnitTest.java new file mode 100644 index 0000000000..2c330c513d --- /dev/null +++ b/core-java/src/test/java/org/baeldung/java/shell/JavaProcessUnitTest.java @@ -0,0 +1,66 @@ +package org.baeldung.java.shell; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.*; +import java.util.concurrent.Executors; +import java.util.function.Consumer; + +public class JavaProcessUnitTest { + private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().startsWith("windows"); + + private static class StreamGobbler implements Runnable { + private InputStream inputStream; + private Consumer consumer; + + public StreamGobbler(InputStream inputStream, Consumer consumer) { + this.inputStream = inputStream; + this.consumer = consumer; + } + + @Override + public void run() { + new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(consumer); + } + } + + private Consumer consumer = new Consumer() { + @Override + public void accept(String s) { + Assert.assertNotNull(s); + } + }; + + private String homeDirectory = System.getProperty("user.home"); + + @Test + public void givenProcess_whenCreatingViaRuntime_shouldSucceed() throws Exception { + Process process; + if (IS_WINDOWS) { + process = Runtime.getRuntime().exec(String.format("cmd.exe /c dir %s", homeDirectory)); + } else { + process = Runtime.getRuntime().exec(String.format("sh -c ls %s", homeDirectory)); + } + StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), consumer); + Executors.newSingleThreadExecutor().submit(streamGobbler); + int exitCode = process.waitFor(); + Assert.assertEquals(0, exitCode); + } + + @Test + public void givenProcess_whenCreatingViaProcessBuilder_shouldSucceed() throws Exception { + ProcessBuilder builder = new ProcessBuilder(); + if (IS_WINDOWS) { + builder.command("cmd.exe", "/c", "dir"); + } else { + builder.command("sh", "-c", "ls"); + } + builder.directory(new File(homeDirectory)); + Process process = builder.start(); + StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), consumer); + Executors.newSingleThreadExecutor().submit(streamGobbler); + int exitCode = process.waitFor(); + Assert.assertEquals(0, exitCode); + } +} diff --git a/core-java/src/test/resources/testFolder/sample_file_1.in b/core-java/src/test/resources/testFolder/sample_file_1.in new file mode 100644 index 0000000000..70c379b63f --- /dev/null +++ b/core-java/src/test/resources/testFolder/sample_file_1.in @@ -0,0 +1 @@ +Hello world \ No newline at end of file diff --git a/core-java/src/test/resources/testFolder/sample_file_2.in b/core-java/src/test/resources/testFolder/sample_file_2.in new file mode 100644 index 0000000000..93b493a513 --- /dev/null +++ b/core-java/src/test/resources/testFolder/sample_file_2.in @@ -0,0 +1 @@ +Hello world ! \ No newline at end of file diff --git a/core-java/src/test/resources/test_md5.txt b/core-java/src/test/resources/test_md5.txt new file mode 100644 index 0000000000..95d09f2b10 --- /dev/null +++ b/core-java/src/test/resources/test_md5.txt @@ -0,0 +1 @@ +hello world \ No newline at end of file diff --git a/couchbase-sdk-intro/.mvn/wrapper/maven-wrapper.jar b/couchbase-sdk-intro/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 5fd4d5023f..0000000000 Binary files a/couchbase-sdk-intro/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/couchbase-sdk-intro/.mvn/wrapper/maven-wrapper.properties b/couchbase-sdk-intro/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index eb91947648..0000000000 --- a/couchbase-sdk-intro/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip \ No newline at end of file diff --git a/couchbase-sdk-intro/pom.xml b/couchbase-sdk-intro/pom.xml deleted file mode 100644 index 1c2ca5ee05..0000000000 --- a/couchbase-sdk-intro/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - 4.0.0 - com.baeldung - couchbase-sdk-intro - 0.1-SNAPSHOT - jar - couchbase-sdk-intro - Intro to the Couchbase SDK - - - - - com.couchbase.client - java-client - ${couchbase.client.version} - - - - - - - maven-compiler-plugin - 2.3.2 - - 1.7 - 1.7 - - - - - - - 1.7 - UTF-8 - 2.2.6 - - - diff --git a/couchbase-sdk-spring-service/.mvn/wrapper/maven-wrapper.jar b/couchbase-sdk-spring-service/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 5fd4d5023f..0000000000 Binary files a/couchbase-sdk-spring-service/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/couchbase-sdk-spring-service/.mvn/wrapper/maven-wrapper.properties b/couchbase-sdk-spring-service/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index eb91947648..0000000000 --- a/couchbase-sdk-spring-service/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip \ No newline at end of file diff --git a/couchbase-sdk-spring-service/mvnw b/couchbase-sdk-spring-service/mvnw deleted file mode 100755 index a1ba1bf554..0000000000 --- a/couchbase-sdk-spring-service/mvnw +++ /dev/null @@ -1,233 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # - # Look for the Apple JDKs first to preserve the existing behaviour, and then look - # for the new JDKs provided by Oracle. - # - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then - # - # Oracle JDKs - # - export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then - # - # Apple JDKs - # - export JAVA_HOME=`/usr/libexec/java_home` - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - 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 - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Migwn, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - 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 - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` -fi - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - local basedir=$(pwd) - local wdir=$(pwd) - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - wdir=$(cd "$wdir/.."; pwd) - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} "$@" diff --git a/couchbase-sdk-spring-service/mvnw.cmd b/couchbase-sdk-spring-service/mvnw.cmd deleted file mode 100644 index 2b934e89dd..0000000000 --- a/couchbase-sdk-spring-service/mvnw.cmd +++ /dev/null @@ -1,145 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -set MAVEN_CMD_LINE_ARGS=%* - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" - -set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% \ No newline at end of file diff --git a/couchbase-sdk/README.md b/couchbase-sdk/README.md new file mode 100644 index 0000000000..9cdcdea012 --- /dev/null +++ b/couchbase-sdk/README.md @@ -0,0 +1,50 @@ +## Couchbase SDK Tutorial Project + +### Relevant Articles: +- [Introduction to Couchbase SDK for Java](http://www.baeldung.com/java-couchbase-sdk) +- [Using Couchbase in a Spring Application](http://www.baeldung.com/couchbase-sdk-spring) +- [Asynchronous Batch Opereations in Couchbase](http://www.baeldung.com/async-batch-operations-in-couchbase) + +### Overview +This Maven project contains the Java code for the Couchbase entities and Spring services +as described in the tutorials, as well as a unit/integration test +for each service implementation. + +### Working with the Code +The project was developed and tested using Java 7 and 8 in the Eclipse-based +Spring Source Toolkit (STS) and therefore should run fine in any +recent version of Eclipse or another IDE of your choice +that supports Java 7 or later. + +### Building the Project +You can also build the project using Maven outside of any IDE: +``` +mvn clean install +``` + +### Package Organization +Java classes for the intro tutorial are in the +org.baeldung.couchbase.intro package. + +Java classes for the Spring service tutorial are in the +org.baeldung.couchbase.spring package hierarchy. + +Java classes for the Asynchronous Couchbase tutorial are in the +org.baeldung.couchbase.async package hierarchy. + + +### Running the tests +The test classes for the Spring service tutorial are: +- org.baeldung.couchbase.spring.service.ClusterServiceTest +- org.baeldung.couchbase.spring.person.PersonCrudServiceTest + +The test classes for the Asynchronous Couchbase tutorial are in the +org.baeldung.couchbase.async package hierarchy: +- org.baeldung.couchbase.async.service.ClusterServiceTest +- org.baeldung.couchbase.async.person.PersonCrudServiceTest + +The test classes may be run as JUnit tests from your IDE +or using the Maven command line: +``` +mvn test +``` diff --git a/couchbase-sdk-intro/mvnw b/couchbase-sdk/mvnw similarity index 100% rename from couchbase-sdk-intro/mvnw rename to couchbase-sdk/mvnw diff --git a/couchbase-sdk-intro/mvnw.cmd b/couchbase-sdk/mvnw.cmd similarity index 100% rename from couchbase-sdk-intro/mvnw.cmd rename to couchbase-sdk/mvnw.cmd diff --git a/couchbase-sdk-spring-service/pom.xml b/couchbase-sdk/pom.xml similarity index 81% rename from couchbase-sdk-spring-service/pom.xml rename to couchbase-sdk/pom.xml index d344f8c756..b7b3d1788f 100644 --- a/couchbase-sdk-spring-service/pom.xml +++ b/couchbase-sdk/pom.xml @@ -3,11 +3,11 @@ 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-spring-service + couchbase-sdk 0.1-SNAPSHOT jar - couchbase-sdk-spring-service - Intro to the Couchbase SDK + couchbase-sdk + Couchbase SDK Tutorials @@ -85,6 +85,17 @@ 1.7 + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + **/*IntegrationTest.java + **/*LiveTest.java + + + @@ -97,6 +108,7 @@ 1.7.12 4.11 3.4 + 2.19.1 diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/CouchbaseEntity.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/CouchbaseEntity.java new file mode 100644 index 0000000000..16e1876719 --- /dev/null +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/CouchbaseEntity.java @@ -0,0 +1,9 @@ +package com.baeldung.couchbase.async; + +public interface CouchbaseEntity { + + String getId(); + + void setId(String id); + +} diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/Person.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/Person.java new file mode 100644 index 0000000000..32ed2ebbe4 --- /dev/null +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/Person.java @@ -0,0 +1,89 @@ +package com.baeldung.couchbase.async.person; + +import com.baeldung.couchbase.async.CouchbaseEntity; + +public class Person implements CouchbaseEntity { + + private String id; + private String type; + private String name; + private String homeTown; + + Person() {} + + public Person(Builder b) { + this.id = b.id; + this.type = b.type; + this.name = b.name; + this.homeTown = b.homeTown; + } + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getHomeTown() { + return homeTown; + } + + public void setHomeTown(String homeTown) { + this.homeTown = homeTown; + } + + public static class Builder { + private String id; + private String type; + private String name; + private String homeTown; + + public static Builder newInstance() { + return new Builder(); + } + + public Person build() { + return new Person(this); + } + + public Builder id(String id) { + this.id = id; + return this; + } + + public Builder type(String type) { + this.type = type; + return this; + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder homeTown(String homeTown) { + this.homeTown = homeTown; + return this; + } + } +} diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/PersonCrudService.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/PersonCrudService.java new file mode 100644 index 0000000000..b2ef985725 --- /dev/null +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/PersonCrudService.java @@ -0,0 +1,26 @@ +package com.baeldung.couchbase.async.person; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +import com.baeldung.couchbase.async.service.AbstractCrudService; +import com.baeldung.couchbase.async.service.BucketService; + +@Service +public class PersonCrudService extends AbstractCrudService { + + @Autowired + public PersonCrudService( + @Qualifier("TutorialBucketService") BucketService bucketService, + PersonDocumentConverter converter) { + super(bucketService, converter); + } + + @PostConstruct + private void init() { + loadBucket(); + } +} diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/PersonDocumentConverter.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/PersonDocumentConverter.java similarity index 88% rename from couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/PersonDocumentConverter.java rename to couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/PersonDocumentConverter.java index cfb20a2bfb..8646cf247a 100644 --- a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/PersonDocumentConverter.java +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/PersonDocumentConverter.java @@ -1,8 +1,8 @@ -package com.baeldung.couchbase.person; +package com.baeldung.couchbase.async.person; import org.springframework.stereotype.Service; -import com.baeldung.couchbase.service.JsonDocumentConverter; +import com.baeldung.couchbase.async.service.JsonDocumentConverter; import com.couchbase.client.java.document.JsonDocument; import com.couchbase.client.java.document.json.JsonObject; diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/RegistrationService.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/RegistrationService.java similarity index 93% rename from couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/RegistrationService.java rename to couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/RegistrationService.java index 53af1c4041..926cd7f4e8 100644 --- a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/RegistrationService.java +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/RegistrationService.java @@ -1,4 +1,4 @@ -package com.baeldung.couchbase.person; +package com.baeldung.couchbase.async.person; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/AbstractBucketService.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/AbstractBucketService.java new file mode 100644 index 0000000000..cbc03cbcda --- /dev/null +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/AbstractBucketService.java @@ -0,0 +1,27 @@ +package com.baeldung.couchbase.async.service; + +import com.couchbase.client.java.Bucket; + +public abstract class AbstractBucketService implements BucketService { + + private ClusterService clusterService; + + private Bucket bucket; + + protected void openBucket() { + bucket = clusterService.openBucket(getBucketName(), getBucketPassword()); + } + + protected abstract String getBucketName(); + + protected abstract String getBucketPassword(); + + public AbstractBucketService(ClusterService clusterService) { + this.clusterService = clusterService; + } + + @Override + public Bucket getBucket() { + return bucket; + } + } diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/AbstractCrudService.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/AbstractCrudService.java new file mode 100644 index 0000000000..861e2404e5 --- /dev/null +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/AbstractCrudService.java @@ -0,0 +1,175 @@ +package com.baeldung.couchbase.async.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.baeldung.couchbase.async.CouchbaseEntity; +import com.couchbase.client.core.BackpressureException; +import com.couchbase.client.core.time.Delay; +import com.couchbase.client.java.AsyncBucket; +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.ReplicaMode; +import com.couchbase.client.java.document.JsonDocument; +import com.couchbase.client.java.util.retry.RetryBuilder; + +import rx.Observable; +import rx.functions.Action1; +import rx.functions.Func1; + +public abstract class AbstractCrudService implements CrudService { + + private static final Logger logger = LoggerFactory.getLogger(AbstractCrudService.class); + + private BucketService bucketService; + private Bucket bucket; + private JsonDocumentConverter converter; + + public AbstractCrudService(BucketService bucketService, JsonDocumentConverter converter) { + this.bucketService = bucketService; + this.converter = converter; + } + + protected void loadBucket() { + bucket = bucketService.getBucket(); + } + + @Override + public void create(T t) { + if(t.getId() == null) { + t.setId(UUID.randomUUID().toString()); + } + JsonDocument doc = converter.toDocument(t); + bucket.insert(doc); + } + + @Override + public T read(String id) { + JsonDocument doc = bucket.get(id); + return (doc == null ? null : converter.fromDocument(doc)); + } + + @Override + public T readFromReplica(String id) { + List docs = bucket.getFromReplica(id, ReplicaMode.FIRST); + return (docs.isEmpty() ? null : converter.fromDocument(docs.get(0))); + } + + @Override + public void update(T t) { + JsonDocument doc = converter.toDocument(t); + bucket.upsert(doc); + } + + @Override + public void delete(String id) { + bucket.remove(id); + } + + @Override + public List readBulk(Iterable ids) { + final AsyncBucket asyncBucket = bucket.async(); + Observable asyncOperation = Observable + .from(ids) + .flatMap(new Func1>() { + public Observable call(String key) { + return asyncBucket.get(key); + } + }); + + final List items = new ArrayList(); + try { + asyncOperation.toBlocking() + .forEach(new Action1() { + public void call(JsonDocument doc) { + T item = converter.fromDocument(doc); + items.add(item); + } + }); + } catch (Exception e) { + logger.error("Error during bulk get", e); + } + + return items; + } + + @Override + public void createBulk(Iterable items) { + final AsyncBucket asyncBucket = bucket.async(); + Observable + .from(items) + .flatMap(new Func1>() { + @SuppressWarnings("unchecked") + @Override + public Observable call(final T t) { + if(t.getId() == null) { + t.setId(UUID.randomUUID().toString()); + } + JsonDocument doc = converter.toDocument(t); + return asyncBucket.insert(doc) + .retryWhen(RetryBuilder + .anyOf(BackpressureException.class) + .delay(Delay.exponential(TimeUnit.MILLISECONDS, 100)) + .max(10) + .build()); + } + }) + .last() + .toBlocking() + .single(); + } + + @Override + public void updateBulk(Iterable items) { + final AsyncBucket asyncBucket = bucket.async(); + Observable + .from(items) + .flatMap(new Func1>() { + @SuppressWarnings("unchecked") + @Override + public Observable call(final T t) { + JsonDocument doc = converter.toDocument(t); + return asyncBucket.upsert(doc) + .retryWhen(RetryBuilder + .anyOf(BackpressureException.class) + .delay(Delay.exponential(TimeUnit.MILLISECONDS, 100)) + .max(10) + .build()); + } + }) + .last() + .toBlocking() + .single(); + } + + @Override + public void deleteBulk(Iterable ids) { + final AsyncBucket asyncBucket = bucket.async(); + Observable + .from(ids) + .flatMap(new Func1>() { + @SuppressWarnings("unchecked") + @Override + public Observable call(String key) { + return asyncBucket.remove(key) + .retryWhen(RetryBuilder + .anyOf(BackpressureException.class) + .delay(Delay.exponential(TimeUnit.MILLISECONDS, 100)) + .max(10) + .build()); + } + }) + .last() + .toBlocking() + .single(); + } + + @Override + public boolean exists(String id) { + return bucket.exists(id); + } +} diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/BucketService.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/BucketService.java new file mode 100644 index 0000000000..28470be99f --- /dev/null +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/BucketService.java @@ -0,0 +1,8 @@ +package com.baeldung.couchbase.async.service; + +import com.couchbase.client.java.Bucket; + +public interface BucketService { + + Bucket getBucket(); +} diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/ClusterService.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/ClusterService.java new file mode 100644 index 0000000000..ee67405b12 --- /dev/null +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/ClusterService.java @@ -0,0 +1,8 @@ +package com.baeldung.couchbase.async.service; + +import com.couchbase.client.java.Bucket; + +public interface ClusterService { + + Bucket openBucket(String name, String password); +} diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java new file mode 100644 index 0000000000..7ce75d21f5 --- /dev/null +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java @@ -0,0 +1,36 @@ +package com.baeldung.couchbase.async.service; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.annotation.PostConstruct; + +import org.springframework.stereotype.Service; + +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.Cluster; +import com.couchbase.client.java.CouchbaseCluster; +import com.couchbase.client.java.env.CouchbaseEnvironment; +import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; + +@Service +public class ClusterServiceImpl implements ClusterService { + + private Cluster cluster; + private Map buckets = new ConcurrentHashMap<>(); + + @PostConstruct + private void init() { + CouchbaseEnvironment env = DefaultCouchbaseEnvironment.create(); + cluster = CouchbaseCluster.create(env, "localhost"); + } + + @Override + synchronized public Bucket openBucket(String name, String password) { + if(!buckets.containsKey(name)) { + Bucket bucket = cluster.openBucket(name, password); + buckets.put(name, bucket); + } + return buckets.get(name); + } +} diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/CrudService.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/CrudService.java new file mode 100644 index 0000000000..5bd0e52214 --- /dev/null +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/CrudService.java @@ -0,0 +1,26 @@ +package com.baeldung.couchbase.async.service; + +import java.util.List; + +public interface CrudService { + + void create(T t); + + T read(String id); + + T readFromReplica(String id); + + void update(T t); + + void delete(String id); + + List readBulk(Iterable ids); + + void createBulk(Iterable items); + + void updateBulk(Iterable items); + + void deleteBulk(Iterable ids); + + boolean exists(String id); +} diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/JsonDocumentConverter.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/JsonDocumentConverter.java similarity index 79% rename from couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/JsonDocumentConverter.java rename to couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/JsonDocumentConverter.java index 87331d2a17..85e14a87ce 100644 --- a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/JsonDocumentConverter.java +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/JsonDocumentConverter.java @@ -1,4 +1,4 @@ -package com.baeldung.couchbase.service; +package com.baeldung.couchbase.async.service; import com.couchbase.client.java.document.JsonDocument; diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java new file mode 100644 index 0000000000..459585d995 --- /dev/null +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java @@ -0,0 +1,32 @@ +package com.baeldung.couchbase.async.service; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +@Service +@Qualifier("TutorialBucketService") +public class TutorialBucketService extends AbstractBucketService { + + @PostConstruct + void init() { + openBucket(); + } + + @Autowired + public TutorialBucketService(ClusterService clusterService) { + super(clusterService); + } + + @Override + protected String getBucketName() { + return "baeldung-tutorial"; + } + + @Override + protected String getBucketPassword() { + return ""; + } +} diff --git a/couchbase-sdk-intro/src/main/java/com/baeldung/couchbase/examples/CodeSnippets.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/intro/CodeSnippets.java similarity index 98% rename from couchbase-sdk-intro/src/main/java/com/baeldung/couchbase/examples/CodeSnippets.java rename to couchbase-sdk/src/main/java/com/baeldung/couchbase/intro/CodeSnippets.java index 088f7af7b1..2cb9e1f4f7 100644 --- a/couchbase-sdk-intro/src/main/java/com/baeldung/couchbase/examples/CodeSnippets.java +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/intro/CodeSnippets.java @@ -1,4 +1,4 @@ -package com.baeldung.couchbase.examples; +package com.baeldung.couchbase.intro; import java.util.List; import java.util.UUID; diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/Person.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/Person.java similarity index 97% rename from couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/Person.java rename to couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/Person.java index 48b7a38780..0348ba1e5f 100644 --- a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/Person.java +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/Person.java @@ -1,4 +1,4 @@ -package com.baeldung.couchbase.person; +package com.baeldung.couchbase.spring.person; public class Person { diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/PersonCrudService.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/PersonCrudService.java similarity index 88% rename from couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/PersonCrudService.java rename to couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/PersonCrudService.java index 0203bf30bb..de035f1d2c 100644 --- a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/PersonCrudService.java +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/PersonCrudService.java @@ -1,4 +1,4 @@ -package com.baeldung.couchbase.person; +package com.baeldung.couchbase.spring.person; import java.util.List; import java.util.UUID; @@ -8,8 +8,9 @@ import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.baeldung.couchbase.service.CrudService; -import com.baeldung.couchbase.service.TutorialBucketService;import com.couchbase.client.java.Bucket; +import com.baeldung.couchbase.spring.service.CrudService; +import com.baeldung.couchbase.spring.service.TutorialBucketService; +import com.couchbase.client.java.Bucket; import com.couchbase.client.java.ReplicaMode; import com.couchbase.client.java.document.JsonDocument; diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/FluentPersonDocumentConverter.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/PersonDocumentConverter.java similarity index 59% rename from couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/FluentPersonDocumentConverter.java rename to couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/PersonDocumentConverter.java index 8210c10b3a..030c9fde27 100644 --- a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/FluentPersonDocumentConverter.java +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/PersonDocumentConverter.java @@ -1,13 +1,13 @@ -package com.baeldung.couchbase.person; +package com.baeldung.couchbase.spring.person; import org.springframework.stereotype.Service; -import com.baeldung.couchbase.service.JsonDocumentConverter; +import com.baeldung.couchbase.spring.service.JsonDocumentConverter; import com.couchbase.client.java.document.JsonDocument; import com.couchbase.client.java.document.json.JsonObject; @Service -public class FluentPersonDocumentConverter implements JsonDocumentConverter { +public class PersonDocumentConverter implements JsonDocumentConverter { @Override public JsonDocument toDocument(Person p) { @@ -21,11 +21,11 @@ public class FluentPersonDocumentConverter implements JsonDocumentConverter { diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/JsonDocumentConverter.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/JsonDocumentConverter.java new file mode 100644 index 0000000000..cf4861fbeb --- /dev/null +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/JsonDocumentConverter.java @@ -0,0 +1,10 @@ +package com.baeldung.couchbase.spring.service; + +import com.couchbase.client.java.document.JsonDocument; + +public interface JsonDocumentConverter { + + JsonDocument toDocument(T t); + + T fromDocument(JsonDocument doc); +} diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/TutorialBucketService.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/TutorialBucketService.java similarity index 93% rename from couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/TutorialBucketService.java rename to couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/TutorialBucketService.java index 903a568399..8a28deb1d6 100644 --- a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/TutorialBucketService.java +++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/TutorialBucketService.java @@ -1,4 +1,4 @@ -package com.baeldung.couchbase.service; +package com.baeldung.couchbase.spring.service; import javax.annotation.PostConstruct; diff --git a/jee7schedule/src/main/webapp/WEB-INF/beans.xml b/couchbase-sdk/src/main/resources/application.properties similarity index 100% rename from jee7schedule/src/main/webapp/WEB-INF/beans.xml rename to couchbase-sdk/src/main/resources/application.properties diff --git a/couchbase-sdk-spring-service/src/main/resources/logback.xml b/couchbase-sdk/src/main/resources/logback.xml similarity index 100% rename from couchbase-sdk-spring-service/src/main/resources/logback.xml rename to couchbase-sdk/src/main/resources/logback.xml diff --git a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTest.java b/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTest.java similarity index 72% rename from spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTest.java rename to couchbase-sdk/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTest.java index ce2daa92cd..3079fc928a 100644 --- a/spring-data-couchbase-2b/src/test/java/org/baeldung/spring/data/couchbase/IntegrationTest.java +++ b/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.data.couchbase; +package com.baeldung.couchbase.async; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { MyCouchbaseConfig.class, IntegrationTestConfig.class }) +@ContextConfiguration(classes = { AsyncIntegrationTestConfig.class }) @TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class }) -public abstract class IntegrationTest { +public abstract class AsyncIntegrationTest { } diff --git a/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTestConfig.java b/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTestConfig.java new file mode 100644 index 0000000000..6afdfe04bd --- /dev/null +++ b/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTestConfig.java @@ -0,0 +1,9 @@ +package com.baeldung.couchbase.async; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan(basePackages={"com.baeldung.couchbase.async"}) +public class AsyncIntegrationTestConfig { +} diff --git a/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java b/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java new file mode 100644 index 0000000000..5907a4cc63 --- /dev/null +++ b/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java @@ -0,0 +1,223 @@ +package com.baeldung.couchbase.async.person; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +import com.baeldung.couchbase.async.AsyncIntegrationTest; +import com.baeldung.couchbase.async.person.Person; +import com.baeldung.couchbase.async.person.PersonCrudService; +import com.baeldung.couchbase.async.person.PersonDocumentConverter; +import com.baeldung.couchbase.async.service.BucketService; +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.document.JsonDocument; + +public class PersonCrudServiceIntegrationTest extends AsyncIntegrationTest { + + @Autowired + private PersonCrudService personService; + + @Autowired + @Qualifier("TutorialBucketService") + private BucketService bucketService; + + @Autowired + private PersonDocumentConverter converter; + + private Bucket bucket; + + @PostConstruct + private void init() { + bucket = bucketService.getBucket(); + } + + @Test + public final void givenRandomPerson_whenCreate_thenPersonPersisted() { + //create person + Person person = randomPerson(); + personService.create(person); + + //check results + assertNotNull(person.getId()); + assertNotNull(bucket.get(person.getId())); + + //cleanup + bucket.remove(person.getId()); + } + + @Test + public final void givenId_whenRead_thenReturnsPerson() { + //create and insert person document + String id = insertRandomPersonDocument().id(); + + //read person and check results + assertNotNull(personService.read(id)); + + //cleanup + bucket.remove(id); + } + + @Test + public final void givenNewHometown_whenUpdate_thenNewHometownPersisted() { + //create and insert person document + JsonDocument doc = insertRandomPersonDocument(); + + //update person + Person expected = converter.fromDocument(doc); + String updatedHomeTown = RandomStringUtils.randomAlphabetic(12); + expected.setHomeTown(updatedHomeTown); + personService.update(expected); + + //check results + JsonDocument actual = bucket.get(expected.getId()); + assertNotNull(actual); + assertNotNull(actual.content()); + assertEquals(expected.getHomeTown(), actual.content().getString("homeTown")); + + //cleanup + bucket.remove(expected.getId()); + } + + @Test + public final void givenRandomPerson_whenDelete_thenPersonNotInBucket() { + //create and insert person document + String id = insertRandomPersonDocument().id(); + + //delete person and check results + personService.delete(id); + assertNull(bucket.get(id)); + } + + @Test + public final void givenIds_whenReadBulk_thenReturnsOnlyPersonsWithMatchingIds() { + List ids = new ArrayList<>(); + + //add some person documents + for(int i=0; i<5; i++) { + ids.add(insertRandomPersonDocument().id()); + } + + //perform bulk read + List persons = personService.readBulk(ids); + + //check results + for(Person person : persons) { + assertTrue(ids.contains(person.getId())); + } + + //cleanup + for(String id : ids) { + bucket.remove(id); + } + } + + @Test + public final void givenPersons_whenInsertBulk_thenPersonsAreInserted() { + + //create some persons + List persons = new ArrayList<>(); + for(int i=0; i<5; i++) { + persons.add(randomPerson()); + } + + //perform bulk insert + personService.createBulk(persons); + + //check results + for(Person person : persons) { + assertNotNull(bucket.get(person.getId())); + } + + //cleanup + for(Person person : persons) { + bucket.remove(person.getId()); + } + } + + @Test + public final void givenPersons_whenUpdateBulk_thenPersonsAreUpdated() { + + List ids = new ArrayList<>(); + + //add some person documents + for(int i=0; i<5; i++) { + ids.add(insertRandomPersonDocument().id()); + } + + //load persons from Couchbase + List persons = new ArrayList<>(); + for(String id : ids) { + persons.add(converter.fromDocument(bucket.get(id))); + } + + //modify persons + for(Person person : persons) { + person.setHomeTown(RandomStringUtils.randomAlphabetic(10)); + } + + //perform bulk update + personService.updateBulk(persons); + + //check results + for(Person person : persons) { + JsonDocument doc = bucket.get(person.getId()); + assertEquals(person.getName(), doc.content().getString("name")); + assertEquals(person.getHomeTown(), doc.content().getString("homeTown")); + } + + //cleanup + for(String id : ids) { + bucket.remove(id); + } + } + + @Test + public void givenIds_whenDeleteBulk_thenPersonsAreDeleted() { + + List ids = new ArrayList<>(); + + //add some person documents + for(int i=0; i<5; i++) { + ids.add(insertRandomPersonDocument().id()); + } + + //perform bulk delete + personService.deleteBulk(ids); + + //check results + for(String id : ids) { + assertNull(bucket.get(id)); + } + + } + + private JsonDocument insertRandomPersonDocument() { + Person expected = randomPersonWithId(); + JsonDocument doc = converter.toDocument(expected); + return bucket.insert(doc); + } + + private Person randomPerson() { + return Person.Builder.newInstance() + .name(RandomStringUtils.randomAlphabetic(10)) + .homeTown(RandomStringUtils.randomAlphabetic(10)) + .build(); + } + + private Person randomPersonWithId() { + return Person.Builder.newInstance() + .id(UUID.randomUUID().toString()) + .name(RandomStringUtils.randomAlphabetic(10)) + .homeTown(RandomStringUtils.randomAlphabetic(10)) + .build(); + } +} diff --git a/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java b/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java new file mode 100644 index 0000000000..08e3728c77 --- /dev/null +++ b/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java @@ -0,0 +1,35 @@ +package com.baeldung.couchbase.async.service; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; + +import com.baeldung.couchbase.async.AsyncIntegrationTest; +import com.baeldung.couchbase.async.AsyncIntegrationTestConfig; +import com.baeldung.couchbase.async.service.ClusterService; +import com.couchbase.client.java.Bucket; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { AsyncIntegrationTestConfig.class }) +@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class }) +public class ClusterServiceIntegrationTest extends AsyncIntegrationTest { + + @Autowired + private ClusterService couchbaseService; + + private Bucket defaultBucket; + + @Test + public void whenOpenBucket_thenBucketIsNotNull() throws Exception { + defaultBucket = couchbaseService.openBucket("default", ""); + assertNotNull(defaultBucket); + assertFalse(defaultBucket.isClosed()); + defaultBucket.close(); + } +} diff --git a/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/IntegrationTest.java b/couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/IntegrationTest.java similarity index 93% rename from couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/IntegrationTest.java rename to couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/IntegrationTest.java index d1cc807f7a..9c0b0a50c1 100644 --- a/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/IntegrationTest.java +++ b/couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/IntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.couchbase; +package com.baeldung.couchbase.spring; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; diff --git a/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/IntegrationTestConfig.java b/couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/IntegrationTestConfig.java similarity index 63% rename from couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/IntegrationTestConfig.java rename to couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/IntegrationTestConfig.java index d593aac52d..ac71911b9b 100644 --- a/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/IntegrationTestConfig.java +++ b/couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/IntegrationTestConfig.java @@ -1,9 +1,9 @@ -package com.baeldung.couchbase; +package com.baeldung.couchbase.spring; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration -@ComponentScan(basePackages={"com.baeldung.couchbase"}) +@ComponentScan(basePackages={"com.baeldung.couchbase.spring"}) public class IntegrationTestConfig { } diff --git a/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/person/PersonCrudServiceTest.java b/couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java similarity index 93% rename from couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/person/PersonCrudServiceTest.java rename to couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java index e19e90769c..b3fadae6ca 100644 --- a/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/person/PersonCrudServiceTest.java +++ b/couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.couchbase.person; +package com.baeldung.couchbase.spring.person; import static org.junit.Assert.*; @@ -8,9 +8,9 @@ import org.apache.commons.lang3.RandomStringUtils; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import com.baeldung.couchbase.IntegrationTest; +import com.baeldung.couchbase.spring.IntegrationTest; -public class PersonCrudServiceTest extends IntegrationTest { +public class PersonCrudServiceIntegrationTest extends IntegrationTest { private static final String CLARK_KENT = "Clark Kent"; private static final String SMALLVILLE = "Smallville"; diff --git a/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/service/ClusterServiceTest.java b/couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java similarity index 82% rename from couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/service/ClusterServiceTest.java rename to couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java index 7795f41c93..f3ee4585a3 100644 --- a/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/service/ClusterServiceTest.java +++ b/couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.couchbase.service; +package com.baeldung.couchbase.spring.service; import static org.junit.Assert.*; @@ -10,14 +10,14 @@ import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; -import com.baeldung.couchbase.IntegrationTest; -import com.baeldung.couchbase.IntegrationTestConfig; +import com.baeldung.couchbase.spring.IntegrationTest; +import com.baeldung.couchbase.spring.IntegrationTestConfig; import com.couchbase.client.java.Bucket; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { IntegrationTestConfig.class }) @TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class }) -public class ClusterServiceTest extends IntegrationTest { +public class ClusterServiceIntegrationTest extends IntegrationTest { @Autowired private ClusterService couchbaseService; diff --git a/deltaspike/.gitignore b/deltaspike/.gitignore new file mode 100644 index 0000000000..aa121e866e --- /dev/null +++ b/deltaspike/.gitignore @@ -0,0 +1,3 @@ +/.idea +baeldung-jee7-seed.iml +/target diff --git a/deltaspike/pom.xml b/deltaspike/pom.xml new file mode 100644 index 0000000000..22cf8f935c --- /dev/null +++ b/deltaspike/pom.xml @@ -0,0 +1,301 @@ + + + 4.0.0 + com.baeldung + deltaspike + 1.0 + war + deltaspike + A starter Java EE 7 webapp which uses DeltaSpike + + http://wildfly.org + + + Apache License, Version 2.0 + repo + http://www.apache.org/licenses/LICENSE-2.0.html + + + + + + + UTF-8 + + + 1.0.2.Final + + + 8.2.1.Final + + + 3.1 + 2.16 + 2.5 + + + 1.7 + 1.7 + + + + + + + + org.wildfly.bom + jboss-javaee-7.0-with-tools + ${version.jboss.bom} + pom + import + + + org.wildfly.bom + jboss-javaee-7.0-with-hibernate + ${version.jboss.bom} + pom + import + + + + + + + + + + + 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 + provided + + + + + + + org.hibernate + hibernate-validator + provided + + + org.slf4j + slf4j-api + + + + + + + org.jboss.spec.javax.faces + jboss-jsf-api_2.2_spec + provided + + + + + + + org.hibernate + hibernate-jpamodelgen + provided + + + + + org.hibernate + hibernate-validator-annotation-processor + provided + + + + + junit + junit + test + + + + + + org.jboss.arquillian.junit + arquillian-junit-container + test + + + + org.jboss.arquillian.protocol + arquillian-protocol-servlet + test + + + + org.jboss.shrinkwrap.resolver + shrinkwrap-resolver-impl-maven + test + + + + org.apache.deltaspike.modules + deltaspike-data-module-api + 1.7.1 + compile + + + + org.apache.deltaspike.modules + deltaspike-data-module-impl + 1.7.1 + runtime + + + + + com.mysema.querydsl + querydsl-apt + 3.7.4 + provided + + + + com.mysema.querydsl + querydsl-jpa + 3.7.4 + + + + org.slf4j + slf4j-log4j12 + 1.6.1 + + + + + + ${project.artifactId} + + + maven-war-plugin + ${version.war.plugin} + + + false + + + + com.mysema.maven + apt-maven-plugin + 1.0.9 + + + + process + + + target/generated-sources/java + com.mysema.query.apt.jpa.JPAAnnotationProcessor + + + + + + + + org.wildfly.plugins + wildfly-maven-plugin + ${version.wildfly.maven.plugin} + + + + + + + + + default + + true + + + + + maven-surefire-plugin + ${version.surefire.plugin} + + true + + + + + + + + + + + + arq-wildfly-managed + + + org.wildfly + wildfly-arquillian-container-managed + test + + + + + diff --git a/deltaspike/src/main/java/baeldung/controller/MemberController.java b/deltaspike/src/main/java/baeldung/controller/MemberController.java new file mode 100644 index 0000000000..7a9e9800f4 --- /dev/null +++ b/deltaspike/src/main/java/baeldung/controller/MemberController.java @@ -0,0 +1,84 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual + * contributors by the @authors tag. See the copyright.txt in the + * distribution for a full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package baeldung.controller; + +import javax.annotation.PostConstruct; +import javax.enterprise.inject.Model; +import javax.enterprise.inject.Produces; +import javax.faces.application.FacesMessage; +import javax.faces.context.FacesContext; +import javax.inject.Inject; +import javax.inject.Named; + +import baeldung.model.Member; +import baeldung.service.MemberRegistration; + +// The @Model stereotype is a convenience mechanism to make this a request-scoped bean that has an +// EL name +// Read more about the @Model stereotype in this FAQ: +// http://www.cdi-spec.org/faq/#accordion6 +@Model +public class MemberController { + + @Inject + private FacesContext facesContext; + + @Inject + private MemberRegistration memberRegistration; + + @Produces + @Named + private Member newMember; + + @PostConstruct + public void initNewMember() { + newMember = new Member(); + } + + public void register() throws Exception { + try { + memberRegistration.register(newMember); + FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_INFO, "Registered!", "Registration successful"); + facesContext.addMessage(null, m); + initNewMember(); + } catch (Exception e) { + String errorMessage = getRootErrorMessage(e); + FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, "Registration unsuccessful"); + facesContext.addMessage(null, m); + } + } + + private String getRootErrorMessage(Exception e) { + // Default to general error message that registration failed. + String errorMessage = "Registration failed. See server log for more information"; + if (e == null) { + // This shouldn't happen, but return the default messages + return errorMessage; + } + + // Start with the exception and recurse to find the root cause + Throwable t = e; + while (t != null) { + // Get the message from the Throwable class instance + errorMessage = t.getLocalizedMessage(); + t = t.getCause(); + } + // This is the root cause message + return errorMessage; + } + +} diff --git a/deltaspike/src/main/java/baeldung/data/EntityManagerProducer.java b/deltaspike/src/main/java/baeldung/data/EntityManagerProducer.java new file mode 100644 index 0000000000..9189dbba74 --- /dev/null +++ b/deltaspike/src/main/java/baeldung/data/EntityManagerProducer.java @@ -0,0 +1,29 @@ +package baeldung.data; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.Default; +import javax.enterprise.inject.Disposes; +import javax.enterprise.inject.Produces; +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.PersistenceUnit; + +@ApplicationScoped +public class EntityManagerProducer { + @PersistenceUnit(unitName = "primary") + private EntityManagerFactory entityManagerFactory; + + @Produces + @Default + @RequestScoped + public EntityManager create() { + return this.entityManagerFactory.createEntityManager(); + } + + public void dispose(@Disposes @Default EntityManager entityManager) { + if (entityManager.isOpen()) { + entityManager.close(); + } + } +} \ No newline at end of file diff --git a/deltaspike/src/main/java/baeldung/data/MemberListProducer.java b/deltaspike/src/main/java/baeldung/data/MemberListProducer.java new file mode 100644 index 0000000000..c1f5fda31d --- /dev/null +++ b/deltaspike/src/main/java/baeldung/data/MemberListProducer.java @@ -0,0 +1,54 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual + * contributors by the @authors tag. See the copyright.txt in the + * distribution for a full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package baeldung.data; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.RequestScoped; +import javax.enterprise.event.Observes; +import javax.enterprise.event.Reception; +import javax.enterprise.inject.Produces; +import javax.inject.Inject; +import javax.inject.Named; +import java.util.List; + +import baeldung.model.Member; + +@RequestScoped +public class MemberListProducer { + + @Inject + private MemberRepository memberRepository; + + private List members; + + // @Named provides access the return value via the EL variable name "members" in the UI (e.g. + // Facelets or JSP view) + @Produces + @Named + public List getMembers() { + return members; + } + + public void onMemberListChanged(@Observes(notifyObserver = Reception.IF_EXISTS) final Member member) { + retrieveAllMembersOrderedByName(); + } + + @PostConstruct + public void retrieveAllMembersOrderedByName() { + members = memberRepository.findAllOrderedByNameWithQueryDSL(); + } +} diff --git a/deltaspike/src/main/java/baeldung/data/MemberRepository.java b/deltaspike/src/main/java/baeldung/data/MemberRepository.java new file mode 100644 index 0000000000..56a4a4e634 --- /dev/null +++ b/deltaspike/src/main/java/baeldung/data/MemberRepository.java @@ -0,0 +1,43 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual + * contributors by the @authors tag. See the copyright.txt in the + * distribution for a full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package baeldung.data; + +import baeldung.model.Member; +import baeldung.model.QMember; +import org.apache.deltaspike.data.api.*; + +import java.util.List; + +@Repository +@EntityManagerConfig(entityManagerResolver = SecondaryEntityManagerResolver.class) +public abstract class MemberRepository extends AbstractEntityRepository implements QueryDslSupport { + + public abstract Member findById(Long id); + + public abstract Member findByEmail(String email); + + @Query("from Member m order by m.name") + public abstract List findAllOrderedByName(); + + public List findAllOrderedByNameWithQueryDSL() { + final QMember member = QMember.member; + return jpaQuery() + .from(member) + .orderBy(member.email.asc()) + .list(member); + } +} diff --git a/deltaspike/src/main/java/baeldung/data/QueryDslRepositoryExtension.java b/deltaspike/src/main/java/baeldung/data/QueryDslRepositoryExtension.java new file mode 100644 index 0000000000..8cb00958ab --- /dev/null +++ b/deltaspike/src/main/java/baeldung/data/QueryDslRepositoryExtension.java @@ -0,0 +1,18 @@ +package baeldung.data; + +import com.mysema.query.jpa.impl.JPAQuery; +import org.apache.deltaspike.data.spi.DelegateQueryHandler; +import org.apache.deltaspike.data.spi.QueryInvocationContext; + +import javax.inject.Inject; + +public class QueryDslRepositoryExtension implements QueryDslSupport, DelegateQueryHandler { + + @Inject + private QueryInvocationContext context; + + @Override + public JPAQuery jpaQuery() { + return new JPAQuery(context.getEntityManager()); + } +} diff --git a/deltaspike/src/main/java/baeldung/data/QueryDslSupport.java b/deltaspike/src/main/java/baeldung/data/QueryDslSupport.java new file mode 100644 index 0000000000..72c33cf1b6 --- /dev/null +++ b/deltaspike/src/main/java/baeldung/data/QueryDslSupport.java @@ -0,0 +1,7 @@ +package baeldung.data; + +import com.mysema.query.jpa.impl.JPAQuery; + +public interface QueryDslSupport { + JPAQuery jpaQuery(); +} diff --git a/deltaspike/src/main/java/baeldung/data/SecondaryEntityManagerProducer.java b/deltaspike/src/main/java/baeldung/data/SecondaryEntityManagerProducer.java new file mode 100644 index 0000000000..41d30d9018 --- /dev/null +++ b/deltaspike/src/main/java/baeldung/data/SecondaryEntityManagerProducer.java @@ -0,0 +1,30 @@ +package baeldung.data; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.Default; +import javax.enterprise.inject.Disposes; +import javax.enterprise.inject.Produces; +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.PersistenceUnit; + +@ApplicationScoped +public class SecondaryEntityManagerProducer { + @PersistenceUnit(unitName = "secondary") + private EntityManagerFactory entityManagerFactory; + + @Produces + @Default + @RequestScoped + @SecondaryPersistenceUnit + public EntityManager create() { + return this.entityManagerFactory.createEntityManager(); + } + + public void dispose(@Disposes @Default EntityManager entityManager) { + if (entityManager.isOpen()) { + entityManager.close(); + } + } +} \ No newline at end of file diff --git a/deltaspike/src/main/java/baeldung/data/SecondaryEntityManagerResolver.java b/deltaspike/src/main/java/baeldung/data/SecondaryEntityManagerResolver.java new file mode 100644 index 0000000000..7faaa1ac49 --- /dev/null +++ b/deltaspike/src/main/java/baeldung/data/SecondaryEntityManagerResolver.java @@ -0,0 +1,18 @@ +package baeldung.data; + +import org.apache.deltaspike.data.api.EntityManagerResolver; + +import javax.inject.Inject; +import javax.persistence.EntityManager; + +public class SecondaryEntityManagerResolver implements EntityManagerResolver { + + @Inject + @SecondaryPersistenceUnit + private EntityManager entityManager; + + @Override + public EntityManager resolveEntityManager() { + return entityManager; + } +} diff --git a/deltaspike/src/main/java/baeldung/data/SecondaryPersistenceUnit.java b/deltaspike/src/main/java/baeldung/data/SecondaryPersistenceUnit.java new file mode 100644 index 0000000000..e60d0aff05 --- /dev/null +++ b/deltaspike/src/main/java/baeldung/data/SecondaryPersistenceUnit.java @@ -0,0 +1,12 @@ +package baeldung.data; + +import javax.inject.Qualifier; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Qualifier +public @interface SecondaryPersistenceUnit { +} diff --git a/deltaspike/src/main/java/baeldung/model/Member.java b/deltaspike/src/main/java/baeldung/model/Member.java new file mode 100644 index 0000000000..e178dcf63a --- /dev/null +++ b/deltaspike/src/main/java/baeldung/model/Member.java @@ -0,0 +1,93 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual + * contributors by the @authors tag. See the copyright.txt in the + * distribution for a full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package baeldung.model; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.Digits; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; + +import org.hibernate.validator.constraints.Email; +import org.hibernate.validator.constraints.NotEmpty; + +@SuppressWarnings("serial") +@Entity +@XmlRootElement +@Table(uniqueConstraints = @UniqueConstraint(columnNames = "email")) +public class Member implements Serializable { + + @Id + @GeneratedValue + private Long id; + + @NotNull + @Size(min = 1, max = 25) + @Pattern(regexp = "[^0-9]*", message = "Must not contain numbers") + private String name; + + @NotNull + @NotEmpty + @Email + private String email; + + @NotNull + @Size(min = 10, max = 12) + @Digits(fraction = 0, integer = 12) + @Column(name = "phone_number") + private String phoneNumber; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } +} diff --git a/deltaspike/src/main/java/baeldung/rest/JaxRsActivator.java b/deltaspike/src/main/java/baeldung/rest/JaxRsActivator.java new file mode 100644 index 0000000000..9357ae0ea6 --- /dev/null +++ b/deltaspike/src/main/java/baeldung/rest/JaxRsActivator.java @@ -0,0 +1,33 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual + * contributors by the @authors tag. See the copyright.txt in the + * distribution for a full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package baeldung.rest; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +/** + * A class extending {@link Application} and annotated with @ApplicationPath is the Java EE 7 "no XML" approach to activating + * JAX-RS. + *

+ *

+ * Resources are served relative to the servlet path specified in the {@link ApplicationPath} annotation. + *

+ */ +@ApplicationPath("/rest") +public class JaxRsActivator extends Application { + /* class body intentionally left blank */ +} diff --git a/deltaspike/src/main/java/baeldung/rest/MemberResourceRESTService.java b/deltaspike/src/main/java/baeldung/rest/MemberResourceRESTService.java new file mode 100644 index 0000000000..5a09e45591 --- /dev/null +++ b/deltaspike/src/main/java/baeldung/rest/MemberResourceRESTService.java @@ -0,0 +1,185 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual + * contributors by the @authors tag. See the copyright.txt in the + * distribution for a full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package baeldung.rest; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Logger; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.persistence.NoResultException; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.ValidationException; +import javax.validation.Validator; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import baeldung.data.MemberRepository; +import baeldung.model.Member; +import baeldung.service.MemberRegistration; + +/** + * JAX-RS Example + *

+ * This class produces a RESTful service to read/write the contents of the members table. + */ +@Path("/members") +@RequestScoped +public class MemberResourceRESTService { + + @Inject + private Logger log; + + @Inject + private Validator validator; + + @Inject + private MemberRepository repository; + + @Inject + MemberRegistration registration; + + @GET + @Produces(MediaType.APPLICATION_JSON) + public List listAllMembers() { + return repository.findAllOrderedByName(); + } + + @GET + @Path("/{id:[0-9][0-9]*}") + @Produces(MediaType.APPLICATION_JSON) + public Member lookupMemberById(@PathParam("id") long id) { + Member member = repository.findById(id); + if (member == null) { + throw new WebApplicationException(Response.Status.NOT_FOUND); + } + return member; + } + + /** + * Creates a new member from the values provided. Performs validation, and will return a JAX-RS response with either 200 ok, + * or with a map of fields, and related errors. + */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response createMember(Member member) { + + Response.ResponseBuilder builder = null; + + try { + // Validates member using bean validation + validateMember(member); + + registration.register(member); + + // Create an "ok" response + builder = Response.ok(); + } catch (ConstraintViolationException ce) { + // Handle bean validation issues + builder = createViolationResponse(ce.getConstraintViolations()); + } catch (ValidationException e) { + // Handle the unique constrain violation + Map responseObj = new HashMap<>(); + responseObj.put("email", "Email taken"); + builder = Response.status(Response.Status.CONFLICT).entity(responseObj); + } catch (Exception e) { + // Handle generic exceptions + Map responseObj = new HashMap<>(); + responseObj.put("error", e.getMessage()); + builder = Response.status(Response.Status.BAD_REQUEST).entity(responseObj); + } + + return builder.build(); + } + + /** + *

+ * Validates the given Member variable and throws validation exceptions based on the type of error. If the error is standard + * bean validation errors then it will throw a ConstraintValidationException with the set of the constraints violated. + *

+ *

+ * If the error is caused because an existing member with the same email is registered it throws a regular validation + * exception so that it can be interpreted separately. + *

+ * + * @param member Member to be validated + * @throws ConstraintViolationException If Bean Validation errors exist + * @throws ValidationException If member with the same email already exists + */ + private void validateMember(Member member) throws ConstraintViolationException, ValidationException { + // Create a bean validator and check for issues. + Set> violations = validator.validate(member); + + if (!violations.isEmpty()) { + throw new ConstraintViolationException(new HashSet>(violations)); + } + + // Check the uniqueness of the email address + if (emailAlreadyExists(member.getEmail())) { + throw new ValidationException("Unique Email Violation"); + } + } + + /** + * Creates a JAX-RS "Bad Request" response including a map of all violation fields, and their message. This can then be used + * by clients to show violations. + * + * @param violations A set of violations that needs to be reported + * @return JAX-RS response containing all violations + */ + private Response.ResponseBuilder createViolationResponse(Set> violations) { + log.fine("Validation completed. violations found: " + violations.size()); + + Map responseObj = new HashMap<>(); + + for (ConstraintViolation violation : violations) { + responseObj.put(violation.getPropertyPath().toString(), violation.getMessage()); + } + + return Response.status(Response.Status.BAD_REQUEST).entity(responseObj); + } + + /** + * Checks if a member with the same email address is already registered. This is the only way to easily capture the + * "@UniqueConstraint(columnNames = "email")" constraint from the Member class. + * + * @param email The email to check + * @return True if the email already exists, and false otherwise + */ + public boolean emailAlreadyExists(String email) { + Member member = null; + try { + member = repository.findByEmail(email); + } catch (NoResultException e) { + // ignore + } + return member != null; + } +} diff --git a/deltaspike/src/main/java/baeldung/service/MemberRegistration.java b/deltaspike/src/main/java/baeldung/service/MemberRegistration.java new file mode 100644 index 0000000000..ec65471622 --- /dev/null +++ b/deltaspike/src/main/java/baeldung/service/MemberRegistration.java @@ -0,0 +1,85 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual + * contributors by the @authors tag. See the copyright.txt in the + * distribution for a full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package baeldung.service; + +import baeldung.data.MemberRepository; +import baeldung.data.SecondaryPersistenceUnit; +import baeldung.model.Member; +import baeldung.model.QMember; + +import javax.ejb.Stateless; +import javax.enterprise.event.Event; +import javax.enterprise.inject.Default; +import javax.inject.Inject; +import javax.persistence.EntityManager; +import javax.persistence.NoResultException; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.ValidationException; +import javax.validation.Validator; +import java.util.HashSet; +import java.util.Set; +import java.util.logging.Logger; + +@Stateless +public class MemberRegistration { + + @Inject + private Logger log; + + @Inject + private MemberRepository repository; + + @Inject + private Event memberEventSrc; + + @Inject + private Validator validator; + + private void validateMember(Member member) throws ConstraintViolationException, ValidationException { + // Create a bean validator and check for issues. + Set> violations = validator.validate(member); + + if (!violations.isEmpty()) { + throw new ConstraintViolationException(new HashSet>(violations)); + } + + // Check the uniqueness of the email address + if (emailAlreadyExists(member.getEmail())) { + throw new ValidationException("Unique Email Violation"); + } + } + + + public void register(Member member) throws Exception { + log.info("Registering " + member.getName()); + validateMember(member); + repository.save(member); + memberEventSrc.fire(member); + } + + public boolean emailAlreadyExists(String email) { + Member member = null; + try { + member = repository.findByEmail(email); + } catch (NoResultException e) { + // ignore + } + return member != null; + } + +} diff --git a/deltaspike/src/main/java/baeldung/util/Resources.java b/deltaspike/src/main/java/baeldung/util/Resources.java new file mode 100644 index 0000000000..2cc1f235d7 --- /dev/null +++ b/deltaspike/src/main/java/baeldung/util/Resources.java @@ -0,0 +1,53 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual + * contributors by the @authors tag. See the copyright.txt in the + * distribution for a full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package baeldung.util; + +import java.util.logging.Logger; + +import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.Produces; +import javax.enterprise.inject.spi.InjectionPoint; +import javax.faces.context.FacesContext; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +/** + * This class uses CDI to alias Java EE resources, such as the persistence context, to CDI beans + *

+ *

+ * Example injection on a managed bean field: + *

+ *

+ *

+ * @Inject
+ * private EntityManager em;
+ * 
+ */ +public class Resources { + + @Produces + public Logger produceLog(InjectionPoint injectionPoint) { + return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName()); + } + + @Produces + @RequestScoped + public FacesContext produceFacesContext() { + return FacesContext.getCurrentInstance(); + } + +} diff --git a/deltaspike/src/main/resources/META-INF/apache-deltaspike.properties b/deltaspike/src/main/resources/META-INF/apache-deltaspike.properties new file mode 100644 index 0000000000..a861ad729a --- /dev/null +++ b/deltaspike/src/main/resources/META-INF/apache-deltaspike.properties @@ -0,0 +1 @@ +globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy=org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy diff --git a/deltaspike/src/main/resources/META-INF/persistence.xml b/deltaspike/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000000..b68c2c1bb1 --- /dev/null +++ b/deltaspike/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,21 @@ + + + + java:jboss/datasources/baeldung-jee7-seedDS + + + + + + + java:jboss/datasources/baeldung-jee7-seed-secondaryDS + + + + + + diff --git a/deltaspike/src/main/resources/import.sql b/deltaspike/src/main/resources/import.sql new file mode 100644 index 0000000000..154f4e9923 --- /dev/null +++ b/deltaspike/src/main/resources/import.sql @@ -0,0 +1,19 @@ +-- +-- JBoss, Home of Professional Open Source +-- Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual +-- contributors by the @authors tag. See the copyright.txt in the +-- distribution for a full listing of individual contributors. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- http://www.apache.org/licenses/LICENSE-2.0 +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +-- You can use this file to load seed data into the database using SQL statements +insert into Member (id, name, email, phone_number) values (0, 'John Smith', 'john.smith@mailinator.com', '2125551212') diff --git a/deltaspike/src/main/webapp/WEB-INF/baeldung-jee7-seed-ds.xml b/deltaspike/src/main/webapp/WEB-INF/baeldung-jee7-seed-ds.xml new file mode 100644 index 0000000000..1a8e350667 --- /dev/null +++ b/deltaspike/src/main/webapp/WEB-INF/baeldung-jee7-seed-ds.xml @@ -0,0 +1,37 @@ + + + + + + + jdbc:h2:mem:baeldung-jee7-seed;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1 + h2 + + sa + sa + + + + diff --git a/deltaspike/src/main/webapp/WEB-INF/baeldung-jee7-seed-secondary-ds.xml b/deltaspike/src/main/webapp/WEB-INF/baeldung-jee7-seed-secondary-ds.xml new file mode 100644 index 0000000000..c4c9afb2e0 --- /dev/null +++ b/deltaspike/src/main/webapp/WEB-INF/baeldung-jee7-seed-secondary-ds.xml @@ -0,0 +1,19 @@ + + + + + + jdbc:h2:mem:baeldung-jee7-seed;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1 + h2 + + sa + sa + + + + diff --git a/deltaspike/src/main/webapp/WEB-INF/beans.xml b/deltaspike/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000000..0090177eb7 --- /dev/null +++ b/deltaspike/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,23 @@ + + + + + diff --git a/deltaspike/src/main/webapp/WEB-INF/faces-config.xml b/deltaspike/src/main/webapp/WEB-INF/faces-config.xml new file mode 100644 index 0000000000..26cf98b669 --- /dev/null +++ b/deltaspike/src/main/webapp/WEB-INF/faces-config.xml @@ -0,0 +1,25 @@ + + + + + diff --git a/deltaspike/src/main/webapp/WEB-INF/templates/default.xhtml b/deltaspike/src/main/webapp/WEB-INF/templates/default.xhtml new file mode 100644 index 0000000000..2f001f8626 --- /dev/null +++ b/deltaspike/src/main/webapp/WEB-INF/templates/default.xhtml @@ -0,0 +1,55 @@ + + + + + baeldung-jee7-seed + + + + +
+
+ +
+
+ + [Template content will be inserted here] + +
+ + +
+
+ diff --git a/deltaspike/src/main/webapp/index.html b/deltaspike/src/main/webapp/index.html new file mode 100644 index 0000000000..dd6c4fb886 --- /dev/null +++ b/deltaspike/src/main/webapp/index.html @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/deltaspike/src/main/webapp/index.xhtml b/deltaspike/src/main/webapp/index.xhtml new file mode 100644 index 0000000000..0f515601be --- /dev/null +++ b/deltaspike/src/main/webapp/index.xhtml @@ -0,0 +1,97 @@ + + + + +

Welcome to WildFly!

+ +
+

You have successfully deployed a Java EE 7 Enterprise + Application.

+

Your application can run on:

+ +
+ + +

Member Registration

+

Enforces annotation-based constraints defined on the + model class.

+ + + + + + + + + + + + + + +

+ + + + +

+
+

Members

+ + No registered members. + + + + Id + #{_member.id} + + + Name + #{_member.name} + + + Email + #{_member.email} + + + Phone # + #{_member.phoneNumber} + + + REST URL + /rest/members/#{_member.id} + + + REST URL for all members: /rest/members + + +
+
diff --git a/deltaspike/src/main/webapp/resources/css/screen.css b/deltaspike/src/main/webapp/resources/css/screen.css new file mode 100644 index 0000000000..0e81d5a9d2 --- /dev/null +++ b/deltaspike/src/main/webapp/resources/css/screen.css @@ -0,0 +1,202 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual + * contributors by the @authors tag. See the copyright.txt in the + * distribution for a full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* Core styles for the page */ +body { + margin: 0; + padding: 0; + background-color: #F1F1F1; + font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif; + font-size: 0.8em; + color:#363636; +} + +#container { + margin: 0 auto; + padding: 0 20px 10px 20px; + border-top: 5px solid #000000; + border-left: 5px solid #8c8f91; + border-right: 5px solid #8c8f91; + border-bottom: 25px solid #8c8f91; + width: 865px; /* subtract 40px from banner width for padding */ + background: #FFFFFF; + background-image: url(#{request.contextPath}/resources/gfx/headerbkg.png); + background-repeat: repeat-x; + padding-top: 30px; + box-shadow: 3px 3px 15px #d5d5d5; +} +#content { + float: left; + width: 500px; + margin: 20px; +} +#aside { + font-size: 0.9em; + width: 275px; + float: left; + margin: 20px 0px; + border: 1px solid #D5D5D5; + background: #F1F1F1; + background-image: url(#{request.contextPath}/resources/gfx/asidebkg.png); + background-repeat: repeat-x; + padding: 20px; +} + +#aside ul { + padding-left: 30px; +} +.dualbrand { + float: right; + padding-right: 10px; +} +#footer { + clear: both; + text-align: center; + color: #666666; + font-size: 0.85em; +} +code { + font-size: 1.1em; +} +a { + color: #4a5d75; + text-decoration: none; +} +a:hover { + color: #369; + text-decoration: underline; +} +h1 { + color:#243446; + font-size: 2.25em; +} +h2 { + font-size: 1em; +} +h3 { + color:#243446; +} +h4 { +} +h5 { +} +h6 { +} +/* Member registration styles */ +span.invalid { + padding-left: 3px; + color: red; +} +form { + padding: 1em; + font: 80%/1 sans-serif; + width: 375px; + border: 1px solid #D5D5D5; +} +label { + float: left; + width: 15%; + margin-left: 20px; + margin-right: 0.5em; + padding-top: 0.2em; + text-align: right; + font-weight: bold; + color:#363636; +} +input { + margin-bottom: 8px; +} +.register { + float: left; + margin-left: 85px; +} + +/* ----- table style ------- */ + + +/* = Simple Table style (black header, grey/white stripes */ + +.simpletablestyle { + background-color:#E6E7E8; + clear:both; + width: 550px; +} + +.simpletablestyle img { + border:0px; +} + +.simpletablestyle td { + height:2em; + padding-left: 6px; + font-size:11px; + padding:5px 5px; +} + +.simpletablestyle th { + background: url(#{request.contextPath}/resources/gfx/bkg-blkheader.png) black repeat-x top left; + font-size:12px; + font-weight:normal; + padding:0 10px 0 5px; + border-bottom:#999999 dotted 1px; +} + +.simpletablestyle thead { + background: url(#{request.contextPath}/resources/gfx/bkg-blkheader.png) black repeat-x top left; + height:31px; + font-size:10px; + font-weight:bold; + color:#FFFFFF; + text-align:left; +} + +.simpletablestyle .header a { + color:#94aebd; +} + +.simpletablestype tfoot { + height: 20px; + font-size: 10px; + font-weight: bold; + background-color: #EAECEE; + text-align: center; +} + +.simpletablestyle tr.header td { + padding: 0px 10px 0px 5px; +} + + +.simpletablestyle .subheader { + background-color: #e6e7e8; + font-size:10px; + font-weight:bold; + color:#000000; + text-align:left; +} + +/* Using new CSS3 selectors for styling*/ +.simpletablestyle tr:nth-child(odd) { + background: #f4f3f3; +} +.simpletablestyle tr:nth-child(even) { + background: #ffffff; +} + +.simpletablestyle td a:hover { + color:#3883ce; + text-decoration:none; +} diff --git a/deltaspike/src/main/webapp/resources/gfx/asidebkg.png b/deltaspike/src/main/webapp/resources/gfx/asidebkg.png new file mode 100644 index 0000000000..543d66ad37 Binary files /dev/null and b/deltaspike/src/main/webapp/resources/gfx/asidebkg.png differ diff --git a/deltaspike/src/main/webapp/resources/gfx/bkg-blkheader.png b/deltaspike/src/main/webapp/resources/gfx/bkg-blkheader.png new file mode 100644 index 0000000000..54b95f349f Binary files /dev/null and b/deltaspike/src/main/webapp/resources/gfx/bkg-blkheader.png differ diff --git a/deltaspike/src/main/webapp/resources/gfx/dualbrand_logo.png b/deltaspike/src/main/webapp/resources/gfx/dualbrand_logo.png new file mode 100644 index 0000000000..68853292cb Binary files /dev/null and b/deltaspike/src/main/webapp/resources/gfx/dualbrand_logo.png differ diff --git a/deltaspike/src/main/webapp/resources/gfx/headerbkg.png b/deltaspike/src/main/webapp/resources/gfx/headerbkg.png new file mode 100644 index 0000000000..2669028ba2 Binary files /dev/null and b/deltaspike/src/main/webapp/resources/gfx/headerbkg.png differ diff --git a/deltaspike/src/main/webapp/resources/gfx/wildfly_400x130.jpg b/deltaspike/src/main/webapp/resources/gfx/wildfly_400x130.jpg new file mode 100644 index 0000000000..667c5a66a3 Binary files /dev/null and b/deltaspike/src/main/webapp/resources/gfx/wildfly_400x130.jpg differ diff --git a/deltaspike/src/test/java/baeldung/test/MemberRegistrationTest.java b/deltaspike/src/test/java/baeldung/test/MemberRegistrationTest.java new file mode 100644 index 0000000000..0270d2d164 --- /dev/null +++ b/deltaspike/src/test/java/baeldung/test/MemberRegistrationTest.java @@ -0,0 +1,84 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual + * contributors by the @authors tag. See the copyright.txt in the + * distribution for a full listing of individual contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package baeldung.test; + +import static org.junit.Assert.assertNotNull; + +import java.io.File; +import java.util.logging.Logger; + +import javax.inject.Inject; + +import baeldung.data.*; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import baeldung.model.Member; +import baeldung.service.MemberRegistration; +import baeldung.util.Resources; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.shrinkwrap.resolver.api.maven.Maven; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(Arquillian.class) +public class MemberRegistrationTest { + @Deployment + public static Archive createTestArchive() { + File[] files = Maven.resolver().loadPomFromFile("pom.xml") + .importRuntimeDependencies().resolve().withTransitivity().asFile(); + + return ShrinkWrap.create(WebArchive.class, "test.war") + .addClasses( + EntityManagerProducer.class, + Member.class, + MemberRegistration.class, + MemberRepository.class, + Resources.class, + QueryDslRepositoryExtension.class, + QueryDslSupport.class, + SecondaryPersistenceUnit.class, + SecondaryEntityManagerProducer.class, + SecondaryEntityManagerResolver.class) + .addAsResource("META-INF/test-persistence.xml", "META-INF/persistence.xml") + .addAsResource("META-INF/apache-deltaspike.properties") + .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") + .addAsWebInfResource("test-ds.xml") + .addAsWebInfResource("test-secondary-ds.xml") + .addAsLibraries(files); + } + + @Inject + MemberRegistration memberRegistration; + + @Inject + Logger log; + + @Test + public void testRegister() throws Exception { + Member newMember = new Member(); + newMember.setName("Jane Doe"); + newMember.setEmail("jane@mailinator.com"); + newMember.setPhoneNumber("2125551234"); + memberRegistration.register(newMember); + assertNotNull(newMember.getId()); + log.info(newMember.getName() + " was persisted with id " + newMember.getId()); + } + +} diff --git a/deltaspike/src/test/resources/META-INF/apache-deltaspike.properties b/deltaspike/src/test/resources/META-INF/apache-deltaspike.properties new file mode 100644 index 0000000000..a861ad729a --- /dev/null +++ b/deltaspike/src/test/resources/META-INF/apache-deltaspike.properties @@ -0,0 +1 @@ +globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy=org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy diff --git a/deltaspike/src/test/resources/META-INF/test-persistence.xml b/deltaspike/src/test/resources/META-INF/test-persistence.xml new file mode 100644 index 0000000000..bc9fbcbeef --- /dev/null +++ b/deltaspike/src/test/resources/META-INF/test-persistence.xml @@ -0,0 +1,21 @@ + + + + java:jboss/datasources/baeldung-jee7-seedTestDS + + + + + + + java:jboss/datasources/baeldung-jee7-seedTestSecondaryDS + + + + + + diff --git a/deltaspike/src/test/resources/arquillian.xml b/deltaspike/src/test/resources/arquillian.xml new file mode 100644 index 0000000000..14f9e53bbd --- /dev/null +++ b/deltaspike/src/test/resources/arquillian.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + target\wildfly-run\wildfly-10.0.0.Final + + + + diff --git a/deltaspike/src/test/resources/test-ds.xml b/deltaspike/src/test/resources/test-ds.xml new file mode 100644 index 0000000000..8c5d022690 --- /dev/null +++ b/deltaspike/src/test/resources/test-ds.xml @@ -0,0 +1,16 @@ + + + + jdbc:h2:mem:baeldung-jee7-seed-test;DB_CLOSE_DELAY=-1 + h2 + + sa + sa + + + + diff --git a/deltaspike/src/test/resources/test-secondary-ds.xml b/deltaspike/src/test/resources/test-secondary-ds.xml new file mode 100644 index 0000000000..f545adc6d6 --- /dev/null +++ b/deltaspike/src/test/resources/test-secondary-ds.xml @@ -0,0 +1,16 @@ + + + + jdbc:h2:mem:baeldung-jee7-seed-test;DB_CLOSE_DELAY=-1 + h2 + + sa + sa + + + + diff --git a/dozer/README.md b/dozer/README.md new file mode 100644 index 0000000000..5e104d914c --- /dev/null +++ b/dozer/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [A Guide to Mapping With Dozer](http://www.baeldung.com/dozer) diff --git a/dozer/pom.xml b/dozer/pom.xml new file mode 100644 index 0000000000..35ac2394a6 --- /dev/null +++ b/dozer/pom.xml @@ -0,0 +1,58 @@ + + 4.0.0 + + com.baeldung + dozer + 1.0 + + dozer + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 7 + 7 + + + + + + + + org.slf4j + slf4j-api + 1.7.5 + + + + org.slf4j + jcl-over-slf4j + 1.7.5 + + + + org.apache.commons + commons-lang3 + 3.2.1 + + + + net.sf.dozer + dozer + 5.5.1 + + + junit + junit + 4.3 + test + + + + + diff --git a/dozer/src/main/java/com/baeldung/dozer/Dest.java b/dozer/src/main/java/com/baeldung/dozer/Dest.java new file mode 100644 index 0000000000..ddffcc29a1 --- /dev/null +++ b/dozer/src/main/java/com/baeldung/dozer/Dest.java @@ -0,0 +1,33 @@ +package com.baeldung.dozer; + +public class Dest { + private String name; + private int age; + + public Dest() { + + } + + public Dest(String name, int age) { + super(); + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/dozer/src/main/java/com/baeldung/dozer/Dest2.java b/dozer/src/main/java/com/baeldung/dozer/Dest2.java new file mode 100644 index 0000000000..bd89af6b2e --- /dev/null +++ b/dozer/src/main/java/com/baeldung/dozer/Dest2.java @@ -0,0 +1,38 @@ +package com.baeldung.dozer; + +public class Dest2 { + private int id; + private int points; + + public Dest2() { + + } + + public Dest2(int id, int points) { + super(); + this.id = id; + this.points = points; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getPoints() { + return points; + } + + public void setPoints(int points) { + this.points = points; + } + + @Override + public String toString() { + return "Dest2 [id=" + id + ", points=" + points + "]"; + } + +} diff --git a/dozer/src/main/java/com/baeldung/dozer/MyCustomConvertor.java b/dozer/src/main/java/com/baeldung/dozer/MyCustomConvertor.java new file mode 100644 index 0000000000..3ae095dc51 --- /dev/null +++ b/dozer/src/main/java/com/baeldung/dozer/MyCustomConvertor.java @@ -0,0 +1,44 @@ +package com.baeldung.dozer; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.dozer.CustomConverter; +import org.dozer.MappingException; + +public class MyCustomConvertor implements CustomConverter { + + @Override + public Object convert(Object dest, Object source, Class arg2, Class arg3) { + if (source == null) { + return null; + } + if (source instanceof Personne3) { + Personne3 person = (Personne3) source; + Date date = new Date(person.getDtob()); + DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + String isoDate = format.format(date); + return new Person3(person.getName(), isoDate); + + } else if (source instanceof Person3) { + Person3 person = (Person3) source; + DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + Date date = null; + try { + date = format.parse(person.getDtob()); + + } catch (ParseException e) { + throw new MappingException("Converter MyCustomConvertor " + "used incorrectly:" + e.getMessage()); + } + long timestamp = date.getTime(); + return new Personne3(person.getName(), timestamp); + + } else { + throw new MappingException("Converter MyCustomConvertor " + "used incorrectly. Arguments passed in were:" + dest + " and " + source); + + } + } + +} diff --git a/dozer/src/main/java/com/baeldung/dozer/Person.java b/dozer/src/main/java/com/baeldung/dozer/Person.java new file mode 100644 index 0000000000..030c6e9de7 --- /dev/null +++ b/dozer/src/main/java/com/baeldung/dozer/Person.java @@ -0,0 +1,43 @@ +package com.baeldung.dozer; + +public class Person { + private String name; + private String nickname; + private int age; + + public Person() { + + } + + public Person(String name, String nickname, int age) { + super(); + this.name = name; + this.nickname = nickname; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/dozer/src/main/java/com/baeldung/dozer/Person2.java b/dozer/src/main/java/com/baeldung/dozer/Person2.java new file mode 100644 index 0000000000..741dfd2fd1 --- /dev/null +++ b/dozer/src/main/java/com/baeldung/dozer/Person2.java @@ -0,0 +1,43 @@ +package com.baeldung.dozer; + +public class Person2 { + private String name; + private String nickname; + private int age; + + public Person2() { + + } + + public Person2(String name, String nickname, int age) { + super(); + this.name = name; + this.nickname = nickname; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/dozer/src/main/java/com/baeldung/dozer/Person3.java b/dozer/src/main/java/com/baeldung/dozer/Person3.java new file mode 100644 index 0000000000..a2a37bed53 --- /dev/null +++ b/dozer/src/main/java/com/baeldung/dozer/Person3.java @@ -0,0 +1,38 @@ +package com.baeldung.dozer; + +public class Person3 { + private String name; + private String dtob; + + public Person3() { + + } + + public Person3(String name, String dtob) { + super(); + this.name = name; + this.dtob = dtob; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDtob() { + return dtob; + } + + public void setDtob(String dtob) { + this.dtob = dtob; + } + + @Override + public String toString() { + return "Person3 [name=" + name + ", dtob=" + dtob + "]"; + } + +} diff --git a/dozer/src/main/java/com/baeldung/dozer/Personne.java b/dozer/src/main/java/com/baeldung/dozer/Personne.java new file mode 100644 index 0000000000..ff301db416 --- /dev/null +++ b/dozer/src/main/java/com/baeldung/dozer/Personne.java @@ -0,0 +1,43 @@ +package com.baeldung.dozer; + +public class Personne { + private String nom; + private String surnom; + private int age; + + public Personne() { + + } + + public Personne(String nom, String surnom, int age) { + super(); + this.nom = nom; + this.surnom = surnom; + this.age = age; + } + + public String getNom() { + return nom; + } + + public void setNom(String nom) { + this.nom = nom; + } + + public String getSurnom() { + return surnom; + } + + public void setSurnom(String surnom) { + this.surnom = surnom; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/dozer/src/main/java/com/baeldung/dozer/Personne2.java b/dozer/src/main/java/com/baeldung/dozer/Personne2.java new file mode 100644 index 0000000000..825c45fb81 --- /dev/null +++ b/dozer/src/main/java/com/baeldung/dozer/Personne2.java @@ -0,0 +1,47 @@ +package com.baeldung.dozer; + +import org.dozer.Mapping; + +public class Personne2 { + private String nom; + private String surnom; + private int age; + + public Personne2() { + + } + + public Personne2(String nom, String surnom, int age) { + super(); + this.nom = nom; + this.surnom = surnom; + this.age = age; + } + + @Mapping("name") + public String getNom() { + return nom; + } + + @Mapping("nickname") + public String getSurnom() { + return surnom; + } + + public void setNom(String nom) { + this.nom = nom; + } + + public void setSurnom(String surnom) { + this.surnom = surnom; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/dozer/src/main/java/com/baeldung/dozer/Personne3.java b/dozer/src/main/java/com/baeldung/dozer/Personne3.java new file mode 100644 index 0000000000..c55f8da20d --- /dev/null +++ b/dozer/src/main/java/com/baeldung/dozer/Personne3.java @@ -0,0 +1,38 @@ +package com.baeldung.dozer; + +public class Personne3 { + private String name; + private long dtob; + + public Personne3() { + + } + + public Personne3(String name, long dtob) { + super(); + this.name = name; + this.dtob = dtob; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getDtob() { + return dtob; + } + + public void setDtob(long dtob) { + this.dtob = dtob; + } + + @Override + public String toString() { + return "Personne3 [name=" + name + ", dtob=" + dtob + "]"; + } + +} diff --git a/dozer/src/main/java/com/baeldung/dozer/Source.java b/dozer/src/main/java/com/baeldung/dozer/Source.java new file mode 100644 index 0000000000..d715a5cc16 --- /dev/null +++ b/dozer/src/main/java/com/baeldung/dozer/Source.java @@ -0,0 +1,32 @@ +package com.baeldung.dozer; + +public class Source { + private String name; + private int age; + + public Source() { + } + + public Source(String name, int age) { + super(); + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/dozer/src/main/java/com/baeldung/dozer/Source2.java b/dozer/src/main/java/com/baeldung/dozer/Source2.java new file mode 100644 index 0000000000..e722f206ca --- /dev/null +++ b/dozer/src/main/java/com/baeldung/dozer/Source2.java @@ -0,0 +1,38 @@ +package com.baeldung.dozer; + +public class Source2 { + private String id; + private double points; + + public Source2() { + + } + + public Source2(String id, double points) { + super(); + this.id = id; + this.points = points; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public double getPoints() { + return points; + } + + public void setPoints(double points) { + this.points = points; + } + + @Override + public String toString() { + return "Source2 [id=" + id + ", points=" + points + "]"; + } + +} diff --git a/dozer/src/test/java/com/baeldung/dozer/DozerTest.java b/dozer/src/test/java/com/baeldung/dozer/DozerTest.java new file mode 100644 index 0000000000..107aab078d --- /dev/null +++ b/dozer/src/test/java/com/baeldung/dozer/DozerTest.java @@ -0,0 +1,199 @@ +package com.baeldung.dozer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.dozer.DozerBeanMapper; +import org.dozer.loader.api.BeanMappingBuilder; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +public class DozerTest { + private final long GMT_DIFFERENCE = 46800000; + + DozerBeanMapper mapper; + + @Before + public void before() throws Exception { + mapper = new DozerBeanMapper(); + } + + BeanMappingBuilder builder = new BeanMappingBuilder() { + + @Override + protected void configure() { + mapping(Person.class, Personne.class).fields("name", "nom").fields("nickname", "surnom"); + + } + }; + BeanMappingBuilder builderMinusAge = new BeanMappingBuilder() { + + @Override + protected void configure() { + mapping(Person.class, Personne.class).fields("name", "nom").fields("nickname", "surnom").exclude("age"); + + } + }; + + @Test + public void givenApiMapper_whenMaps_thenCorrect() { + mapper.addMapping(builder); + + Personne frenchAppPerson = new Personne("Sylvester Stallone", "Rambo", 70); + Person englishAppPerson = mapper.map(frenchAppPerson, Person.class); + + assertEquals(englishAppPerson.getName(), frenchAppPerson.getNom()); + assertEquals(englishAppPerson.getNickname(), frenchAppPerson.getSurnom()); + assertEquals(englishAppPerson.getAge(), frenchAppPerson.getAge()); + } + + @Test + public void givenApiMapper_whenMapsOnlySpecifiedFields_thenCorrect() { + mapper.addMapping(builderMinusAge); + + Person englishAppPerson = new Person("Sylvester Stallone", "Rambo", 70); + Personne frenchAppPerson = mapper.map(englishAppPerson, Personne.class); + + assertEquals(frenchAppPerson.getNom(), englishAppPerson.getName()); + assertEquals(frenchAppPerson.getSurnom(), englishAppPerson.getNickname()); + assertEquals(frenchAppPerson.getAge(), 0); + } + + @Test + public void givenApiMapper_whenMapsBidirectionally_thenCorrect() { + mapper.addMapping(builder); + + Person englishAppPerson = new Person("Sylvester Stallone", "Rambo", 70); + Personne frenchAppPerson = mapper.map(englishAppPerson, Personne.class); + + assertEquals(frenchAppPerson.getNom(), englishAppPerson.getName()); + assertEquals(frenchAppPerson.getSurnom(), englishAppPerson.getNickname()); + assertEquals(frenchAppPerson.getAge(), englishAppPerson.getAge()); + } + + @Test + public void givenSourceObjectAndDestClass_whenMapsSameNameFieldsCorrectly_thenCorrect() { + Source source = new Source("Baeldung", 10); + Dest dest = mapper.map(source, Dest.class); + assertEquals(dest.getName(), "Baeldung"); + assertEquals(dest.getAge(), 10); + } + + @Test + public void givenSourceObjectAndDestObject_whenMapsSameNameFieldsCorrectly_thenCorrect() { + Source source = new Source("Baeldung", 10); + Dest dest = new Dest(); + mapper.map(source, dest); + assertEquals(dest.getName(), "Baeldung"); + assertEquals(dest.getAge(), 10); + } + + @Test + public void givenSourceAndDestWithDifferentFieldTypes_whenMapsAndAutoConverts_thenCorrect() { + Source2 source = new Source2("320", 15.2); + Dest2 dest = mapper.map(source, Dest2.class); + assertEquals(dest.getId(), 320); + assertEquals(dest.getPoints(), 15); + } + + @Test + public void givenSrcAndDestWithDifferentFieldNamesWithCustomMapper_whenMaps_thenCorrect() { + configureMapper("dozer_mapping.xml"); + + Personne frenchAppPerson = new Personne("Sylvester Stallone", "Rambo", 70); + Person englishAppPerson = mapper.map(frenchAppPerson, Person.class); + + assertEquals(englishAppPerson.getName(), frenchAppPerson.getNom()); + assertEquals(englishAppPerson.getNickname(), frenchAppPerson.getSurnom()); + assertEquals(englishAppPerson.getAge(), frenchAppPerson.getAge()); + } + + @Test + public void givenSrcAndDestWithDifferentFieldNamesWithCustomMapper_whenMapsBidirectionally_thenCorrect() { + configureMapper("dozer_mapping.xml"); + + Person englishAppPerson = new Person("Dwayne Johnson", "The Rock", 44); + Personne frenchAppPerson = mapper.map(englishAppPerson, Personne.class); + + assertEquals(frenchAppPerson.getNom(), englishAppPerson.getName()); + assertEquals(frenchAppPerson.getSurnom(), englishAppPerson.getNickname()); + assertEquals(frenchAppPerson.getAge(), englishAppPerson.getAge()); + } + + @Ignore("place dozer_mapping.xml at a location of your choice and copy/paste the path after file: in configureMapper method") + @Test + public void givenMappingFileOutsideClasspath_whenMaps_thenCorrect() { + configureMapper("file:e:/dozer_mapping.xml"); + + Person englishAppPerson = new Person("Marshall Bruce Mathers III", "Eminem", 43); + Personne frenchAppPerson = mapper.map(englishAppPerson, Personne.class); + + assertEquals(frenchAppPerson.getNom(), englishAppPerson.getName()); + assertEquals(frenchAppPerson.getSurnom(), englishAppPerson.getNickname()); + assertEquals(frenchAppPerson.getAge(), englishAppPerson.getAge()); + } + + @Test + public void givenSrcAndDest_whenMapsOnlySpecifiedFields_thenCorrect() { + configureMapper("dozer_mapping2.xml"); + + Person englishAppPerson = new Person("Shawn Corey Carter", "Jay Z", 46); + Personne frenchAppPerson = mapper.map(englishAppPerson, Personne.class); + + assertEquals(frenchAppPerson.getNom(), englishAppPerson.getName()); + assertEquals(frenchAppPerson.getSurnom(), englishAppPerson.getNickname()); + assertEquals(frenchAppPerson.getAge(), 0); + } + + @Test + public void givenAnnotatedSrcFields_whenMapsToRightDestField_thenCorrect() { + Person2 englishAppPerson = new Person2("Jean-Claude Van Damme", "JCVD", 55); + Personne2 frenchAppPerson = mapper.map(englishAppPerson, Personne2.class); + assertEquals(frenchAppPerson.getNom(), englishAppPerson.getName()); + assertEquals(frenchAppPerson.getSurnom(), englishAppPerson.getNickname()); + assertEquals(frenchAppPerson.getAge(), englishAppPerson.getAge()); + } + + @Test + public void givenAnnotatedSrcFields_whenMapsToRightDestFieldBidirectionally_thenCorrect() { + Personne2 frenchAppPerson = new Personne2("Jason Statham", "transporter", 49); + Person2 englishAppPerson = mapper.map(frenchAppPerson, Person2.class); + assertEquals(englishAppPerson.getName(), frenchAppPerson.getNom()); + assertEquals(englishAppPerson.getNickname(), frenchAppPerson.getSurnom()); + assertEquals(englishAppPerson.getAge(), frenchAppPerson.getAge()); + } + + @Test + public void givenSrcAndDestWithDifferentFieldTypes_whenAbleToCustomConvert_thenCorrect() { + configureMapper("dozer_custom_convertor.xml"); + + String dateTime = "2007-06-26T21:22:39Z"; + long timestamp = new Long("1182882159000"); + + Person3 person = new Person3("Rich", dateTime); + Personne3 person0 = mapper.map(person, Personne3.class); + + long timestampToTest = person0.getDtob(); + assertTrue(timestampToTest == timestamp || timestampToTest >= timestamp - GMT_DIFFERENCE || timestampToTest <= timestamp + GMT_DIFFERENCE); + } + + @Test + public void givenSrcAndDestWithDifferentFieldTypes_whenAbleToCustomConvertBidirectionally_thenCorrect() { + long timestamp = new Long("1182882159000"); + Personne3 person = new Personne3("Rich", timestamp); + configureMapper("dozer_custom_convertor.xml"); + + Person3 person0 = mapper.map(person, Person3.class); + String timestampTest = person0.getDtob(); + + assertTrue(timestampTest.charAt(10) == 'T' && timestampTest.charAt(19) == 'Z'); + } + + public void configureMapper(String... mappingFileUrls) { + mapper.setMappingFiles(Arrays.asList(mappingFileUrls)); + } + +} diff --git a/dozer/src/test/resources/dozer_custom_convertor.xml b/dozer/src/test/resources/dozer_custom_convertor.xml new file mode 100644 index 0000000000..0cbe5a7918 --- /dev/null +++ b/dozer/src/test/resources/dozer_custom_convertor.xml @@ -0,0 +1,14 @@ + + + + + + com.baeldung.dozer.Personne3 + com.baeldung.dozer.Person3 + + + + + \ No newline at end of file diff --git a/dozer/src/test/resources/dozer_mapping.xml b/dozer/src/test/resources/dozer_mapping.xml new file mode 100644 index 0000000000..13f31db11a --- /dev/null +++ b/dozer/src/test/resources/dozer_mapping.xml @@ -0,0 +1,17 @@ + + + + com.baeldung.dozer.Personne + com.baeldung.dozer.Person + + nom + name + + + surnom + nickname + + + \ No newline at end of file diff --git a/dozer/src/test/resources/dozer_mapping2.xml b/dozer/src/test/resources/dozer_mapping2.xml new file mode 100644 index 0000000000..63411568b6 --- /dev/null +++ b/dozer/src/test/resources/dozer_mapping2.xml @@ -0,0 +1,17 @@ + + + + com.baeldung.dozer.Personne + com.baeldung.dozer.Person + + nom + name + + + surnom + nickname + + + \ No newline at end of file diff --git a/feign/README.md b/feign/README.md new file mode 100644 index 0000000000..149f7320d9 --- /dev/null +++ b/feign/README.md @@ -0,0 +1,8 @@ +## Feign Hypermedia Client ## + +This is the implementation of a [spring-hypermedia-api][1] client using Feign. + +[1]: https://github.com/eugenp/spring-hypermedia-api + +###Relevant Articles: +- [Intro to Feign](http://www.baeldung.com/intro-to-feign) diff --git a/feign/pom.xml b/feign/pom.xml new file mode 100644 index 0000000000..af61883f1b --- /dev/null +++ b/feign/pom.xml @@ -0,0 +1,99 @@ + + + 4.0.0 + + com.baeldung.feign + feign-client + 1.0.0-SNAPSHOT + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + .. + + + + UTF-8 + + + + + io.github.openfeign + feign-core + 9.3.1 + + + io.github.openfeign + feign-okhttp + 9.3.1 + + + io.github.openfeign + feign-gson + 9.3.1 + + + io.github.openfeign + feign-slf4j + 9.3.1 + + + org.slf4j + slf4j-api + 1.7.21 + + + org.apache.logging.log4j + log4j-core + 2.6.2 + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.6.2 + + + org.projectlombok + lombok + 1.16.10 + provided + + + junit + junit + 4.12 + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + true + + + + org.springframework.boot + spring-boot-maven-plugin + 1.4.0.RELEASE + + + + + diff --git a/feign/src/main/java/com/baeldung/feign/BookControllerFeignClientBuilder.java b/feign/src/main/java/com/baeldung/feign/BookControllerFeignClientBuilder.java new file mode 100644 index 0000000000..9c0c359d88 --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/BookControllerFeignClientBuilder.java @@ -0,0 +1,26 @@ +package com.baeldung.feign; + +import com.baeldung.feign.clients.BookClient; +import feign.Feign; +import feign.Logger; +import feign.gson.GsonDecoder; +import feign.gson.GsonEncoder; +import feign.okhttp.OkHttpClient; +import feign.slf4j.Slf4jLogger; +import lombok.Getter; + +@Getter +public class BookControllerFeignClientBuilder { + private BookClient bookClient = createClient(BookClient.class, + "http://localhost:8081/api/books"); + + private static T createClient(Class type, String uri) { + return Feign.builder() + .client(new OkHttpClient()) + .encoder(new GsonEncoder()) + .decoder(new GsonDecoder()) + .logger(new Slf4jLogger(type)) + .logLevel(Logger.Level.FULL) + .target(type, uri); + } +} diff --git a/feign/src/main/java/com/baeldung/feign/clients/BookClient.java b/feign/src/main/java/com/baeldung/feign/clients/BookClient.java new file mode 100644 index 0000000000..df20ef8f93 --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/clients/BookClient.java @@ -0,0 +1,21 @@ +package com.baeldung.feign.clients; + +import com.baeldung.feign.models.Book; +import com.baeldung.feign.models.BookResource; +import feign.Headers; +import feign.Param; +import feign.RequestLine; + +import java.util.List; + +public interface BookClient { + @RequestLine("GET /{isbn}") + BookResource findByIsbn(@Param("isbn") String isbn); + + @RequestLine("GET") + List findAll(); + + @RequestLine("POST") + @Headers("Content-Type: application/json") + void create(Book book); +} diff --git a/feign/src/main/java/com/baeldung/feign/models/Book.java b/feign/src/main/java/com/baeldung/feign/models/Book.java new file mode 100644 index 0000000000..cda4412e27 --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/models/Book.java @@ -0,0 +1,18 @@ +package com.baeldung.feign.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class Book { + private String isbn; + private String author; + private String title; + private String synopsis; + private String language; +} diff --git a/feign/src/main/java/com/baeldung/feign/models/BookResource.java b/feign/src/main/java/com/baeldung/feign/models/BookResource.java new file mode 100644 index 0000000000..7902db9fe8 --- /dev/null +++ b/feign/src/main/java/com/baeldung/feign/models/BookResource.java @@ -0,0 +1,14 @@ +package com.baeldung.feign.models; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@ToString +@NoArgsConstructor +@AllArgsConstructor +public class BookResource { + private Book book; +} diff --git a/feign/src/main/resources/log4j2.xml b/feign/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..659c5fda0e --- /dev/null +++ b/feign/src/main/resources/log4j2.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/feign/src/test/java/com/baeldung/feign/clients/BookClientTest.java b/feign/src/test/java/com/baeldung/feign/clients/BookClientTest.java new file mode 100644 index 0000000000..e7e058a336 --- /dev/null +++ b/feign/src/test/java/com/baeldung/feign/clients/BookClientTest.java @@ -0,0 +1,58 @@ +package com.baeldung.feign.clients; + +import com.baeldung.feign.BookControllerFeignClientBuilder; +import com.baeldung.feign.models.Book; +import com.baeldung.feign.models.BookResource; +import lombok.extern.slf4j.Slf4j; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +@Slf4j +@RunWith(JUnit4.class) +public class BookClientTest { + private BookClient bookClient; + + @Before + public void setup() { + BookControllerFeignClientBuilder feignClientBuilder = new BookControllerFeignClientBuilder(); + bookClient = feignClientBuilder.getBookClient(); + } + + @Test + public void givenBookClient_shouldRunSuccessfully() throws Exception { + List books = bookClient.findAll().stream() + .map(BookResource::getBook) + .collect(Collectors.toList()); + assertTrue(books.size() > 2); + log.info("{}", books); + } + + @Test + public void givenBookClient_shouldFindOneBook() throws Exception { + Book book = bookClient.findByIsbn("0151072558").getBook(); + assertThat(book.getAuthor(), containsString("Orwell")); + log.info("{}", book); + } + + @Test + public void givenBookClient_shouldPostBook() throws Exception { + String isbn = UUID.randomUUID().toString(); + Book book = new Book(isbn, "Me", "It's me!", null, null); + bookClient.create(book); + + book = bookClient.findByIsbn(isbn).getBook(); + assertThat(book.getAuthor(), is("Me")); + log.info("{}", book); + } +} diff --git a/flyway/.gitignore b/flyway/.gitignore new file mode 100644 index 0000000000..9cdd5b9542 --- /dev/null +++ b/flyway/.gitignore @@ -0,0 +1,4 @@ +.classpath +.project +.settings +target/ \ No newline at end of file diff --git a/flyway/README.MD b/flyway/README.MD new file mode 100644 index 0000000000..1b3f3c05ee --- /dev/null +++ b/flyway/README.MD @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Database Migrations with Flyway](http://www.baeldung.com/database-migrations-with-flyway) diff --git a/flyway/db/migration/V1_0__create_employee_schema.sql b/flyway/db/migration/V1_0__create_employee_schema.sql new file mode 100644 index 0000000000..b6167bfacc --- /dev/null +++ b/flyway/db/migration/V1_0__create_employee_schema.sql @@ -0,0 +1,8 @@ +CREATE TABLE IF NOT EXISTS `employee` ( + +`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY, +`name` varchar(20), +`email` varchar(50), +`date_of_birth` timestamp + +)ENGINE=InnoDB DEFAULT CHARSET=UTF8; \ No newline at end of file diff --git a/flyway/db/migration/V2_0__create_department_schema.sql b/flyway/db/migration/V2_0__create_department_schema.sql new file mode 100644 index 0000000000..c85cc81353 --- /dev/null +++ b/flyway/db/migration/V2_0__create_department_schema.sql @@ -0,0 +1,8 @@ +CREATE TABLE IF NOT EXISTS `department` ( + +`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY, +`name` varchar(20) + +)ENGINE=InnoDB DEFAULT CHARSET=UTF8; + +ALTER TABLE `employee` ADD `dept_id` int AFTER `email`; \ No newline at end of file diff --git a/flyway/myFlywayConfig.properties b/flyway/myFlywayConfig.properties new file mode 100644 index 0000000000..8bb102930a --- /dev/null +++ b/flyway/myFlywayConfig.properties @@ -0,0 +1,5 @@ +flyway.user=root +flyway.password=mysql +flyway.schemas=app-db +flyway.url=jdbc:mysql://localhost:3306/ +flyway.locations=filesystem:db/migration \ No newline at end of file diff --git a/flyway/pom.xml b/flyway/pom.xml new file mode 100644 index 0000000000..d53bc7dc41 --- /dev/null +++ b/flyway/pom.xml @@ -0,0 +1,34 @@ + + 4.0.0 + com.baeldung + flyway + 1.0 + flyway + A sample project to demonstrate Flyway migrations + + + mysql + mysql-connector-java + 6.0.3 + + + + + + org.flywaydb + flyway-maven-plugin + 4.0.3 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/gatling/README.md b/gatling/README.md new file mode 100644 index 0000000000..5c81c4bd6a --- /dev/null +++ b/gatling/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Intro to Gatling](http://www.baeldung.com/introduction-to-gatling) diff --git a/gson-jackson-performance/README.md b/gson-jackson-performance/README.md deleted file mode 100644 index 5b08f6cdec..0000000000 --- a/gson-jackson-performance/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Performance of Gson and Jackson - -Standalone java programs to measure the performance of both JSON APIs based on file size and object graph complexity. diff --git a/gson-jackson-performance/pom.xml b/gson-jackson-performance/pom.xml deleted file mode 100644 index 1ea43bd7fa..0000000000 --- a/gson-jackson-performance/pom.xml +++ /dev/null @@ -1,72 +0,0 @@ - - 4.0.0 - - com.baeldung - gson-jackson-performance - 0.0.1-SNAPSHOT - jar - - gson-jackson-performance - http://maven.apache.org - - - UTF-8 - - - - gson-jackson-performance - - - src/main/resources - true - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - - - - - - - - com.google.code.gson - gson - 2.5 - - - - com.fasterxml.jackson.core - jackson-databind - 2.7.1-1 - - - - junit - junit - 3.8.1 - test - - - - log4j - log4j - 1.2.17 - - - - - - - diff --git a/gson-jackson-performance/src/main/java/com/baeldung/data/complex/ComplexDataGeneration.java b/gson-jackson-performance/src/main/java/com/baeldung/data/complex/ComplexDataGeneration.java deleted file mode 100644 index b69d306edf..0000000000 --- a/gson-jackson-performance/src/main/java/com/baeldung/data/complex/ComplexDataGeneration.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.baeldung.data.complex; - -import java.util.ArrayList; -import java.util.List; - -import com.baeldung.data.utility.Utility; -import com.baeldung.pojo.complex.AddressDetails; -import com.baeldung.pojo.complex.ContactDetails; -import com.baeldung.pojo.complex.CustomerAddressDetails; -import com.baeldung.pojo.complex.CustomerPortfolioComplex; - -/** - * - * This class is responsible for generating data for complex type object - */ - -public class ComplexDataGeneration { - - public static CustomerPortfolioComplex generateData() { - List customerAddressDetailsList = new ArrayList(); - for (int i = 0; i < 600000; i++) { - CustomerAddressDetails customerAddressDetails = new CustomerAddressDetails(); - customerAddressDetails.setAge(20); - customerAddressDetails.setFirstName(Utility.generateRandomName()); - customerAddressDetails.setLastName(Utility.generateRandomName()); - - List addressDetailsList = new ArrayList(); - customerAddressDetails.setAddressDetails(addressDetailsList); - - for (int j = 0; j < 2; j++) { - AddressDetails addressDetails = new AddressDetails(); - addressDetails.setZipcode(Utility.generateRandomZip()); - addressDetails.setAddress(Utility.generateRandomAddress()); - - List contactDetailsList = new ArrayList(); - addressDetails.setContactDetails(contactDetailsList); - - for (int k = 0; k < 2; k++) { - ContactDetails contactDetails = new ContactDetails(); - contactDetails.setLandline(Utility.generateRandomPhone()); - contactDetails.setMobile(Utility.generateRandomPhone()); - contactDetailsList.add(contactDetails); - contactDetails = null; - } - - addressDetailsList.add(addressDetails); - addressDetails = null; - contactDetailsList = null; - } - customerAddressDetailsList.add(customerAddressDetails); - customerAddressDetails = null; - - if (i % 6000 == 0) { - Runtime.getRuntime().gc(); - } - } - - CustomerPortfolioComplex customerPortfolioComplex = new CustomerPortfolioComplex(); - customerPortfolioComplex.setCustomerAddressDetailsList(customerAddressDetailsList); - customerAddressDetailsList = null; - return customerPortfolioComplex; - } -} diff --git a/gson-jackson-performance/src/main/java/com/baeldung/data/complex/ComplexDataGson.java b/gson-jackson-performance/src/main/java/com/baeldung/data/complex/ComplexDataGson.java deleted file mode 100644 index b97893e8f1..0000000000 --- a/gson-jackson-performance/src/main/java/com/baeldung/data/complex/ComplexDataGson.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.baeldung.data.complex; - -import java.util.Map; - -import org.apache.log4j.Logger; -import com.baeldung.data.utility.Utility; -import com.baeldung.pojo.complex.CustomerPortfolioComplex; - -import com.google.gson.Gson; - -/** - * - * This class is responsible for performing functions for Complex type - * GSON like - * Java to Json - * Json to Map - * Json to Java Object - */ - -public class ComplexDataGson { - - private static final Logger logger = Logger.getLogger(ComplexDataGson.class); - - static Gson gson = new Gson(); - - static long generateJsonAvgTime = 0L; - - static long parseJsonToMapAvgTime = 0L; - - static long parseJsonToActualObjectAvgTime = 0L; - - public static void main(String[] args) { - CustomerPortfolioComplex customerPortfolioComplex = ComplexDataGeneration.generateData(); - int j = 50; - for (int i = 0; i < j; i++) { - logger.info("-------Round " + (i + 1)); - String jsonStr = generateJson(customerPortfolioComplex); - logger.info("Size of Complex content Jackson :: " + Utility.bytesIntoMB(jsonStr.getBytes().length)); - logger.info("--------------------------------------------------------------------------"); - parseJsonToMap(jsonStr); - parseJsonToActualObject(jsonStr); - jsonStr = null; - } - - generateJsonAvgTime = generateJsonAvgTime / j; - parseJsonToMapAvgTime = parseJsonToMapAvgTime / j; - parseJsonToActualObjectAvgTime = parseJsonToActualObjectAvgTime / j; - - logger.info("--------------------------------------------------------------------------"); - logger.info("Average Time to Generate JSON : " + generateJsonAvgTime); - logger.info("Average Time to Parse JSON To Map : " + parseJsonToMapAvgTime); - logger.info("Average Time to Parse JSON To Actual Object : " + parseJsonToActualObjectAvgTime); - logger.info("--------------------------------------------------------------------------"); - } - - private static String generateJson(CustomerPortfolioComplex customerPortfolioComplex) { - Runtime.getRuntime().gc(); - long startParsTime = System.nanoTime(); - String json = gson.toJson(customerPortfolioComplex); - long endParsTime = System.nanoTime(); - long elapsedTime = endParsTime - startParsTime; - generateJsonAvgTime = generateJsonAvgTime + elapsedTime; - logger.info("Json Generation Time(ms):: " + elapsedTime); - return json; - } - - private static void parseJsonToMap(String jsonStr) { - long startParsTime = System.nanoTime(); - Map parsedMap = gson.fromJson(jsonStr , Map.class); - long endParsTime = System.nanoTime(); - long elapsedTime = endParsTime - startParsTime; - parseJsonToMapAvgTime = parseJsonToMapAvgTime + elapsedTime; - logger.info("Generating Map from json Time(ms):: " + elapsedTime); - logger.info("--------------------------------------------------------------------------"); - parsedMap = null; - Runtime.getRuntime().gc(); - } - - private static void parseJsonToActualObject(String jsonStr) { - long startParsTime = System.nanoTime(); - CustomerPortfolioComplex customerPortfolioComplex = gson.fromJson(jsonStr , CustomerPortfolioComplex.class); - long endParsTime = System.nanoTime(); - long elapsedTime = endParsTime - startParsTime; - parseJsonToActualObjectAvgTime = parseJsonToActualObjectAvgTime + elapsedTime; - logger.info("Generating Actual Object from json Time(ms):: " + elapsedTime); - logger.info("--------------------------------------------------------------------------"); - customerPortfolioComplex = null; - Runtime.getRuntime().gc(); - - } -} diff --git a/gson-jackson-performance/src/main/java/com/baeldung/data/complex/ComplexDataJackson.java b/gson-jackson-performance/src/main/java/com/baeldung/data/complex/ComplexDataJackson.java deleted file mode 100644 index 07a210fb37..0000000000 --- a/gson-jackson-performance/src/main/java/com/baeldung/data/complex/ComplexDataJackson.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.baeldung.data.complex; - -import java.io.IOException; -import java.util.Map; - -import com.baeldung.data.utility.Utility; -import org.apache.log4j.Logger; -import com.baeldung.pojo.complex.CustomerPortfolioComplex; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * - * This class is responsible for performing functions for Complex type - * Jackson like - * Java to Json - * Json to Map - * Json to Java Object - */ - -public class ComplexDataJackson { - - private static final Logger logger = Logger.getLogger(ComplexDataJackson.class); - - static ObjectMapper mapper = new ObjectMapper(); - - static long generateJsonAvgTime = 0L; - - static long parseJsonToMapAvgTime = 0L; - - static long parseJsonToActualObjectAvgTime = 0L; - - public static void main(String[] args) throws IOException { - CustomerPortfolioComplex customerPortfolioComplex = ComplexDataGeneration.generateData(); - int j = 50; - for (int i = 0; i < j; i++) { - logger.info("-------Round " + (i + 1)); - String jsonStr = generateJson(customerPortfolioComplex); - logger.info("Size of Complex content Jackson :: " + Utility.bytesIntoMB(jsonStr.getBytes().length)); - logger.info("--------------------------------------------------------------------------"); - parseJsonToMap(jsonStr); - parseJsonToActualObject(jsonStr); - jsonStr = null; - } - - generateJsonAvgTime = generateJsonAvgTime / j; - parseJsonToMapAvgTime = parseJsonToMapAvgTime / j; - parseJsonToActualObjectAvgTime = parseJsonToActualObjectAvgTime / j; - - logger.info("--------------------------------------------------------------------------"); - logger.info("Average Time to Generate JSON : " + generateJsonAvgTime); - logger.info("Average Time to Parse JSON To Map : " + parseJsonToMapAvgTime); - logger.info("Average Time to Parse JSON To Actual Object : " + parseJsonToActualObjectAvgTime); - logger.info("--------------------------------------------------------------------------"); - } - - private static String generateJson(CustomerPortfolioComplex customerPortfolioComplex) - throws JsonProcessingException { - Runtime.getRuntime().gc(); - long startParsTime = System.nanoTime(); - String json = mapper.writeValueAsString(customerPortfolioComplex); - long endParsTime = System.nanoTime(); - long elapsedTime = endParsTime - startParsTime; - generateJsonAvgTime = generateJsonAvgTime + elapsedTime; - logger.info("Json Generation Time(ms):: " + elapsedTime); - return json; - } - - private static void parseJsonToMap(String jsonStr) throws JsonParseException , JsonMappingException , IOException { - long startParsTime = System.nanoTime(); - Map parsedMap = mapper.readValue(jsonStr , Map.class); - long endParsTime = System.nanoTime(); - long elapsedTime = endParsTime - startParsTime; - parseJsonToMapAvgTime = parseJsonToMapAvgTime + elapsedTime; - logger.info("Generating Map from json Time(ms):: " + elapsedTime); - parsedMap = null; - Runtime.getRuntime().gc(); - - } - - private static void parseJsonToActualObject(String jsonStr) throws JsonParseException , JsonMappingException , - IOException { - long startParsTime = System.nanoTime(); - CustomerPortfolioComplex customerPortfolioComplex = mapper.readValue(jsonStr , CustomerPortfolioComplex.class); - long endParsTime = System.nanoTime(); - long elapsedTime = endParsTime - startParsTime; - parseJsonToActualObjectAvgTime = parseJsonToActualObjectAvgTime + elapsedTime; - logger.info("Generating Actual Object from json Time(ms):: " + elapsedTime); - customerPortfolioComplex = null; - Runtime.getRuntime().gc(); - } -} diff --git a/gson-jackson-performance/src/main/java/com/baeldung/data/simple/SimpleDataGeneration.java b/gson-jackson-performance/src/main/java/com/baeldung/data/simple/SimpleDataGeneration.java deleted file mode 100644 index 1e186adc72..0000000000 --- a/gson-jackson-performance/src/main/java/com/baeldung/data/simple/SimpleDataGeneration.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.baeldung.data.simple; - -import java.util.ArrayList; -import java.util.List; - -import com.baeldung.data.utility.Utility; -import com.baeldung.pojo.simple.Customer; -import com.baeldung.pojo.simple.CustomerPortfolioSimple; - -/** - * - * This class is responsible for generating data for simple type object - */ - -public class SimpleDataGeneration { - - public static CustomerPortfolioSimple generateData() { - List customerList = new ArrayList(); - for (int i = 0; i < 1; i++) { - Customer customer = new Customer(); - customer.setAge(20); - customer.setFirstName(Utility.generateRandomName()); - customer.setLastName(Utility.generateRandomName()); - - customerList.add(customer); - customer = null; - - } - - CustomerPortfolioSimple customerPortfolioSimple = new CustomerPortfolioSimple(); - customerPortfolioSimple.setCustomerLists(customerList); - customerList = null; - return customerPortfolioSimple; - } -} diff --git a/gson-jackson-performance/src/main/java/com/baeldung/data/simple/SimpleDataGson.java b/gson-jackson-performance/src/main/java/com/baeldung/data/simple/SimpleDataGson.java deleted file mode 100644 index b190313462..0000000000 --- a/gson-jackson-performance/src/main/java/com/baeldung/data/simple/SimpleDataGson.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.baeldung.data.simple; - -import java.util.Map; - -import org.apache.log4j.Logger; -import com.baeldung.data.utility.Utility; -import com.baeldung.pojo.simple.CustomerPortfolioSimple; - -import com.google.gson.Gson; - -/** - * - * This class is responsible for performing functions for Simple type - * GSON like - * Java to Json - * Json to Map - * Json to Java Object - */ - -public class SimpleDataGson { - - private static final Logger logger = Logger.getLogger(SimpleDataGson.class); - - static Gson gson = new Gson(); - - static long generateJsonAvgTime = 0L; - - static long parseJsonToMapAvgTime = 0L; - - static long parseJsonToActualObjectAvgTime = 0L; - - public static void main(String[] args) { - CustomerPortfolioSimple customerPortfolioSimple = SimpleDataGeneration.generateData(); - String jsonStr = null; - int j = 5; - for (int i = 0; i < j; i++) { - logger.info("-------Round " + (i + 1)); - jsonStr = generateJson(customerPortfolioSimple); - logger.info("Size of Simple content Gson :: " + Utility.bytesIntoMB(jsonStr.getBytes().length)); - logger.info("--------------------------------------------------------------------------"); - parseJsonToMap(jsonStr); - parseJsonToActualObject(jsonStr); - jsonStr = null; - } - generateJsonAvgTime = generateJsonAvgTime / j; - parseJsonToMapAvgTime = parseJsonToMapAvgTime / j; - parseJsonToActualObjectAvgTime = parseJsonToActualObjectAvgTime / j; - - logger.info("--------------------------------------------------------------------------"); - logger.info("Average Time to Generate JSON : " + generateJsonAvgTime); - logger.info("Average Time to Parse JSON To Map : " + parseJsonToMapAvgTime); - logger.info("Average Time to Parse JSON To Actual Object : " + parseJsonToActualObjectAvgTime); - logger.info("--------------------------------------------------------------------------"); - } - - private static String generateJson(CustomerPortfolioSimple customerPortfolioSimple) { - Runtime.getRuntime().gc(); - long startParsTime = System.nanoTime(); - String json = gson.toJson(customerPortfolioSimple); - long endParsTime = System.nanoTime(); - long elapsedTime = endParsTime - startParsTime; - generateJsonAvgTime = generateJsonAvgTime + elapsedTime; - logger.info("Json Generation Time(ms):: " + elapsedTime); - return json; - } - - private static void parseJsonToMap(String jsonStr) { - long startParsTime = System.nanoTime(); - Map parsedMap = gson.fromJson(jsonStr , Map.class); - long endParsTime = System.nanoTime(); - long elapsedTime = endParsTime - startParsTime; - parseJsonToMapAvgTime = parseJsonToMapAvgTime + elapsedTime; - logger.info("Generating Map from json Time(ms):: " + elapsedTime); - logger.info("--------------------------------------------------------------------------"); - parsedMap = null; - Runtime.getRuntime().gc(); - - } - - private static void parseJsonToActualObject(String jsonStr) { - long startParsTime = System.nanoTime(); - CustomerPortfolioSimple customerPortfolioSimple = gson.fromJson(jsonStr , CustomerPortfolioSimple.class); - long endParsTime = System.nanoTime(); - long elapsedTime = endParsTime - startParsTime; - parseJsonToActualObjectAvgTime = parseJsonToActualObjectAvgTime + elapsedTime; - logger.info("Generating Actual Object from json Time(ms):: " + elapsedTime); - logger.info("--------------------------------------------------------------------------"); - customerPortfolioSimple = null; - Runtime.getRuntime().gc(); - } -} diff --git a/gson-jackson-performance/src/main/java/com/baeldung/data/simple/SimpleDataJackson.java b/gson-jackson-performance/src/main/java/com/baeldung/data/simple/SimpleDataJackson.java deleted file mode 100644 index 9330333604..0000000000 --- a/gson-jackson-performance/src/main/java/com/baeldung/data/simple/SimpleDataJackson.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.baeldung.data.simple; - -import java.io.IOException; -import java.util.Map; - -import com.baeldung.data.utility.Utility; -import org.apache.log4j.Logger; -import com.baeldung.pojo.simple.CustomerPortfolioSimple; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * - * This class is responsible for performing functions for Simple type - * Jackson like - * Java to Json - * Json to Map - * Json to Java Object - */ - -public class SimpleDataJackson { - - private static final Logger logger = Logger.getLogger(SimpleDataJackson.class); - - static ObjectMapper mapper = new ObjectMapper(); - - static long generateJsonAvgTime = 0L; - - static long parseJsonToMapAvgTime = 0L; - - static long parseJsonToActualObjectAvgTime = 0L; - - public static void main(String[] args) throws IOException { - CustomerPortfolioSimple customerPortfolioSimple = SimpleDataGeneration.generateData(); - int j = 50; - for (int i = 0; i < j; i++) { - logger.info("-------Round " + (i + 1)); - String jsonStr = generateJson(customerPortfolioSimple); - logger.info("Size of Simple content Jackson :: " + Utility.bytesIntoMB(jsonStr.getBytes().length)); - logger.info("--------------------------------------------------------------------------"); - - parseJsonToMap(jsonStr); - parseJsonToActualObject(jsonStr); - jsonStr = null; - } - - generateJsonAvgTime = generateJsonAvgTime / j; - parseJsonToMapAvgTime = parseJsonToMapAvgTime / j; - parseJsonToActualObjectAvgTime = parseJsonToActualObjectAvgTime / j; - - logger.info("--------------------------------------------------------------------------"); - logger.info("Average Time to Generate JSON : " + generateJsonAvgTime); - logger.info("Average Time to Parse JSON To Map : " + parseJsonToMapAvgTime); - logger.info("Average Time to Parse JSON To Actual Object : " + parseJsonToActualObjectAvgTime); - logger.info("--------------------------------------------------------------------------"); - } - - private static String generateJson(CustomerPortfolioSimple customerPortfolioSimple) throws JsonProcessingException { - Runtime.getRuntime().gc(); - long startParsTime = System.nanoTime(); - String json = mapper.writeValueAsString(customerPortfolioSimple); - long endParsTime = System.nanoTime(); - long elapsedTime = endParsTime - startParsTime; - generateJsonAvgTime = generateJsonAvgTime + elapsedTime; - logger.info("Json Generation Time(ms):: " + elapsedTime); - return json; - } - - private static void parseJsonToMap(String jsonStr) throws JsonParseException , JsonMappingException , IOException { - long startParsTime = System.nanoTime(); - Map parsedMap = mapper.readValue(jsonStr , Map.class); - long endParsTime = System.nanoTime(); - long elapsedTime = endParsTime - startParsTime; - parseJsonToMapAvgTime = parseJsonToMapAvgTime + elapsedTime; - logger.info("Generating Map from json Time(ms):: " + elapsedTime); - logger.info("--------------------------------------------------------------------------"); - parsedMap = null; - Runtime.getRuntime().gc(); - } - - private static void parseJsonToActualObject(String jsonStr) throws JsonParseException , JsonMappingException , - IOException { - long startParsTime = System.nanoTime(); - CustomerPortfolioSimple customerPortfolioSimple = mapper.readValue(jsonStr , CustomerPortfolioSimple.class); - long endParsTime = System.nanoTime(); - long elapsedTime = endParsTime - startParsTime; - parseJsonToActualObjectAvgTime = parseJsonToActualObjectAvgTime + elapsedTime; - logger.info("Generating Actual Object from json Time(ms):: " + elapsedTime); - customerPortfolioSimple = null; - Runtime.getRuntime().gc(); - } -} diff --git a/gson-jackson-performance/src/main/java/com/baeldung/data/utility/Utility.java b/gson-jackson-performance/src/main/java/com/baeldung/data/utility/Utility.java deleted file mode 100644 index 8b0c402e47..0000000000 --- a/gson-jackson-performance/src/main/java/com/baeldung/data/utility/Utility.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.baeldung.data.utility; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.util.Random; - -public class Utility { - - public static String generateRandomName() { - char[] chars = "abcdefghijklmnopqrstuvwxyz ".toCharArray(); - StringBuilder sb = new StringBuilder(); - Random random = new Random(); - for (int i = 0; i < 8; i++) { - char c = chars[random.nextInt(chars.length)]; - sb.append(c); - } - return sb.toString(); - } - - public static String generateRandomAddress() { - char[] chars = "abcdefghijklmnopqrstuvwxyz ".toCharArray(); - StringBuilder sb = new StringBuilder(); - Random random = new Random(); - for (int i = 0; i < 30; i++) { - char c = chars[random.nextInt(chars.length)]; - sb.append(c); - } - return sb.toString(); - } - - public static String generateRandomZip() { - char[] chars = "1234567890".toCharArray(); - StringBuilder sb = new StringBuilder(); - Random random = new Random(); - for (int i = 0; i < 8; i++) { - char c = chars[random.nextInt(chars.length)]; - sb.append(c); - } - return sb.toString(); - } - - public static String generateRandomPhone() { - char[] chars = "1234567890".toCharArray(); - StringBuilder sb = new StringBuilder(); - Random random = new Random(); - for (int i = 0; i < 10; i++) { - char c = chars[random.nextInt(chars.length)]; - sb.append(c); - } - return sb.toString(); - } - - public static String readFile(String fileName , Class clazz) throws IOException { - String dir = clazz.getResource("/").getFile(); - dir = dir + "/" + fileName; - - BufferedReader br = new BufferedReader(new FileReader(dir)); - try { - StringBuilder sb = new StringBuilder(); - String line = br.readLine(); - - while (line != null) { - sb.append(line); - sb.append(System.lineSeparator()); - line = br.readLine(); - } - return sb.toString(); - } finally { - br.close(); - } - } - - public static String bytesIntoMB(long bytes) { - long kilobyte = 1024; - long megabyte = kilobyte * 1024; - - if ((bytes >= 0) && (bytes < kilobyte)) { - return bytes + " B"; - - } else if ((bytes >= kilobyte) && (bytes < megabyte)) { - return (bytes / kilobyte) + " KB"; - - } else if ((bytes >= megabyte)) { - return (bytes / megabyte) + " MB"; - } - - return null; - } -} diff --git a/gson-jackson-performance/src/main/java/com/baeldung/pojo/complex/AddressDetails.java b/gson-jackson-performance/src/main/java/com/baeldung/pojo/complex/AddressDetails.java deleted file mode 100644 index 79725a97bd..0000000000 --- a/gson-jackson-performance/src/main/java/com/baeldung/pojo/complex/AddressDetails.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.baeldung.pojo.complex; - -import java.util.List; - -public class AddressDetails { - - private String address; - - private String zipcode; - - private List contactDetails; - - public String getZipcode() { - return zipcode; - } - - public void setZipcode(String zipcode) { - this.zipcode = zipcode; - } - - public List getContactDetails() { - return contactDetails; - } - - public void setContactDetails(List contactDetails) { - this.contactDetails = contactDetails; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - -} diff --git a/gson-jackson-performance/src/main/java/com/baeldung/pojo/complex/ContactDetails.java b/gson-jackson-performance/src/main/java/com/baeldung/pojo/complex/ContactDetails.java deleted file mode 100644 index 164fe3f470..0000000000 --- a/gson-jackson-performance/src/main/java/com/baeldung/pojo/complex/ContactDetails.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.baeldung.pojo.complex; - -public class ContactDetails { - - private String mobile; - - private String landline; - - public String getMobile() { - return mobile; - } - - public void setMobile(String mobile) { - this.mobile = mobile; - } - - public String getLandline() { - return landline; - } - - public void setLandline(String landline) { - this.landline = landline; - } - -} diff --git a/gson-jackson-performance/src/main/java/com/baeldung/pojo/complex/CustomerAddressDetails.java b/gson-jackson-performance/src/main/java/com/baeldung/pojo/complex/CustomerAddressDetails.java deleted file mode 100644 index 9bc5951716..0000000000 --- a/gson-jackson-performance/src/main/java/com/baeldung/pojo/complex/CustomerAddressDetails.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.baeldung.pojo.complex; - -import java.util.List; - -import com.baeldung.pojo.simple.Customer; - -public class CustomerAddressDetails extends Customer { - - private List addressDetails; - - public List getAddressDetails() { - return addressDetails; - } - - public void setAddressDetails(List addressDetails) { - this.addressDetails = addressDetails; - } -} diff --git a/gson-jackson-performance/src/main/java/com/baeldung/pojo/complex/CustomerPortfolioComplex.java b/gson-jackson-performance/src/main/java/com/baeldung/pojo/complex/CustomerPortfolioComplex.java deleted file mode 100644 index 13f9d240b8..0000000000 --- a/gson-jackson-performance/src/main/java/com/baeldung/pojo/complex/CustomerPortfolioComplex.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.baeldung.pojo.complex; - -import java.util.List; - -public class CustomerPortfolioComplex { - - private List customerAddressDetailsList; - - public List getCustomerAddressDetailsList() { - return customerAddressDetailsList; - } - - public void setCustomerAddressDetailsList(List customerAddressDetailsList) { - this.customerAddressDetailsList = customerAddressDetailsList; - } - -} diff --git a/gson-jackson-performance/src/main/java/com/baeldung/pojo/simple/CustomerPortfolioSimple.java b/gson-jackson-performance/src/main/java/com/baeldung/pojo/simple/CustomerPortfolioSimple.java deleted file mode 100644 index 7cb684813c..0000000000 --- a/gson-jackson-performance/src/main/java/com/baeldung/pojo/simple/CustomerPortfolioSimple.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.baeldung.pojo.simple; - -import java.util.List; - -public class CustomerPortfolioSimple { - - private List customerLists; - - public List getCustomerLists() { - return customerLists; - } - - public void setCustomerLists(List customerLists) { - this.customerLists = customerLists; - } -} diff --git a/gson-jackson-performance/src/main/resources/log4j.properties b/gson-jackson-performance/src/main/resources/log4j.properties deleted file mode 100644 index 371cbc9048..0000000000 --- a/gson-jackson-performance/src/main/resources/log4j.properties +++ /dev/null @@ -1,16 +0,0 @@ -# Root logger option -log4j.rootLogger=DEBUG, file - -# Redirect log messages to console -# log4j.appender.stdout=org.apache.log4j.ConsoleAppender -# log4j.appender.stdout.Target=System.out -# log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -# log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n - -# Redirect log messages to a log file, support file rolling. -log4j.appender.file=org.apache.log4j.RollingFileAppender -log4j.appender.file.File=log4j-application.log -log4j.appender.file.MaxFileSize=5MB -log4j.appender.file.MaxBackupIndex=10 -log4j.appender.file.layout=org.apache.log4j.PatternLayout -log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file diff --git a/gson/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch b/gson/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch deleted file mode 100644 index 627021fb96..0000000000 --- a/gson/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/gson/README.md b/gson/README.md index 67651b732e..60c80477b1 100644 --- a/gson/README.md +++ b/gson/README.md @@ -5,3 +5,4 @@ ### Relevant Articles: - [Gson Deserialization Cookbook](http://www.baeldung.com/gson-deserialization-guide) +- [Jackson vs Gson](http://www.baeldung.com/jackson-vs-gson) diff --git a/gson/pom.xml b/gson/pom.xml index 4f331f6fd9..d864c289c2 100644 --- a/gson/pom.xml +++ b/gson/pom.xml @@ -19,7 +19,7 @@ com.google.guava guava - 18.0 + ${guava.version} commons-io diff --git a/gson/src/main/java/org/baeldung/gson/entities/ActorGson.java b/gson/src/main/java/org/baeldung/gson/entities/ActorGson.java new file mode 100644 index 0000000000..92468683bf --- /dev/null +++ b/gson/src/main/java/org/baeldung/gson/entities/ActorGson.java @@ -0,0 +1,57 @@ +package org.baeldung.gson.entities; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +public class ActorGson { + + private String imdbId; + private Date dateOfBirth; + private List filmography; + + public ActorGson(String imdbId, Date dateOfBirth, List filmography) { + super(); + this.imdbId = imdbId; + this.dateOfBirth = dateOfBirth; + this.filmography = filmography; + } + + @Override + public String toString() { + return "ActorGson [imdbId=" + imdbId + ", dateOfBirth=" + formatDateOfBirth() + ", filmography=" + filmography + "]"; + } + + public String getImdbId() { + return imdbId; + } + + public void setImdbId(String imdbId) { + this.imdbId = imdbId; + } + + public Date getDateOfBirth() { + return dateOfBirth; + } + + public void setDateOfBirth(Date dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } + + public List getFilmography() { + return filmography; + } + + public void setFilmography(List filmography) { + this.filmography = filmography; + } + + private String formatDateOfBirth() { + final DateFormat formatter = new SimpleDateFormat("EEE MMM dd hh:mm:ss zzz yyyy"); + formatter.setTimeZone(TimeZone.getTimeZone("GMT")); + return formatter.format(dateOfBirth); + } + +} \ No newline at end of file diff --git a/gson/src/main/java/org/baeldung/gson/entities/Movie.java b/gson/src/main/java/org/baeldung/gson/entities/Movie.java new file mode 100644 index 0000000000..ee688f228d --- /dev/null +++ b/gson/src/main/java/org/baeldung/gson/entities/Movie.java @@ -0,0 +1,48 @@ +package org.baeldung.gson.entities; + +import java.util.List; + +public class Movie { + + private String imdbId; + private String director; + private List actors; + + public Movie(String imdbID, String director, List actors) { + super(); + this.imdbId = imdbID; + this.director = director; + this.actors = actors; + } + + @Override + public String toString() { + return "Movie [imdbId=" + imdbId + ", director=" + director + ", actors=" + actors + "]"; + } + + public String getImdbID() { + return imdbId; + } + + public void setImdbID(String imdbID) { + this.imdbId = imdbID; + } + + public String getDirector() { + return director; + } + + public void setDirector(String director) { + this.director = director; + } + + public List getActors() { + return actors; + } + + public void setActors(List actors) { + this.actors = actors; + } + + +} \ No newline at end of file diff --git a/gson/src/main/java/org/baeldung/gson/entities/MovieWithNullValue.java b/gson/src/main/java/org/baeldung/gson/entities/MovieWithNullValue.java new file mode 100644 index 0000000000..fe62d51ffb --- /dev/null +++ b/gson/src/main/java/org/baeldung/gson/entities/MovieWithNullValue.java @@ -0,0 +1,46 @@ +package org.baeldung.gson.entities; + +import com.google.gson.annotations.Expose; + +import java.util.List; + +public class MovieWithNullValue { + + @Expose + private String imdbId; + private String director; + + @Expose + private List actors; + + public MovieWithNullValue(String imdbID, String director, List actors) { + super(); + this.imdbId = imdbID; + this.director = director; + this.actors = actors; + } + + public String getImdbID() { + return imdbId; + } + + public void setImdbID(String imdbID) { + this.imdbId = imdbID; + } + + public String getDirector() { + return director; + } + + public void setDirector(String director) { + this.director = director; + } + + public List getActors() { + return actors; + } + + public void setActors(List actors) { + this.actors = actors; + } +} \ No newline at end of file diff --git a/gson/src/main/java/org/baeldung/gson/serialization/ActorGsonDeserializer.java b/gson/src/main/java/org/baeldung/gson/serialization/ActorGsonDeserializer.java new file mode 100644 index 0000000000..016e3ba1e2 --- /dev/null +++ b/gson/src/main/java/org/baeldung/gson/serialization/ActorGsonDeserializer.java @@ -0,0 +1,46 @@ +package org.baeldung.gson.serialization; + +import java.lang.reflect.Type; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; + +import org.baeldung.gson.entities.ActorGson; + +import com.google.gson.JsonArray; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; + +public class ActorGsonDeserializer implements JsonDeserializer { + + private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); + + @Override + public ActorGson deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + + final JsonObject jsonObject = json.getAsJsonObject(); + + final JsonElement jsonImdbId = jsonObject.get("imdbId"); + final JsonElement jsonDateOfBirth = jsonObject.get("dateOfBirth"); + final JsonArray jsonFilmography = jsonObject.getAsJsonArray("filmography"); + + final ArrayList filmList = new ArrayList(); + if (jsonFilmography != null) { + for (int i = 0; i < jsonFilmography.size(); i++) { + filmList.add(jsonFilmography.get(i).getAsString()); + } + } + + ActorGson actorGson = null; + try { + actorGson = new ActorGson(jsonImdbId.getAsString(), sdf.parse(jsonDateOfBirth.getAsString()), filmList); + } catch (final ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return actorGson; + } +} \ No newline at end of file diff --git a/gson/src/main/java/org/baeldung/gson/serialization/ActorGsonSerializer.java b/gson/src/main/java/org/baeldung/gson/serialization/ActorGsonSerializer.java new file mode 100644 index 0000000000..8f2cd10f5a --- /dev/null +++ b/gson/src/main/java/org/baeldung/gson/serialization/ActorGsonSerializer.java @@ -0,0 +1,33 @@ +package org.baeldung.gson.serialization; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import org.baeldung.gson.entities.ActorGson; + +import java.lang.reflect.Type; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.stream.Collectors; + +public class ActorGsonSerializer implements JsonSerializer { + + private SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); + + @Override + public JsonElement serialize(ActorGson actor, Type type, JsonSerializationContext jsonSerializationContext) { + + JsonObject actorJsonObj = new JsonObject(); + actorJsonObj.addProperty("IMDB Code", actor.getImdbId()); + actorJsonObj.addProperty("Date Of Birth", actor.getDateOfBirth() != null ? sdf.format(actor.getDateOfBirth()) : null); + actorJsonObj.addProperty("N° Film: ", actor.getFilmography() != null ? actor.getFilmography().size() : null); + actorJsonObj.addProperty("filmography", actor.getFilmography() != null ? convertFilmography(actor.getFilmography()) : null); + + return actorJsonObj; + } + + private String convertFilmography(List filmography) { + return filmography.stream().collect(Collectors.joining("-")); + } +} \ No newline at end of file diff --git a/gson/src/test/java/org/baeldung/gson/deserialization/GsonDeserializeTest.java b/gson/src/test/java/org/baeldung/gson/deserialization/GsonDeserializeTest.java new file mode 100644 index 0000000000..3844c55cd8 --- /dev/null +++ b/gson/src/test/java/org/baeldung/gson/deserialization/GsonDeserializeTest.java @@ -0,0 +1,40 @@ +package org.baeldung.gson.deserialization; + +import java.text.ParseException; + +import org.baeldung.gson.entities.ActorGson; +import org.baeldung.gson.entities.Movie; +import org.baeldung.gson.serialization.ActorGsonDeserializer; +import org.junit.Assert; +import org.junit.Test; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public class GsonDeserializeTest { + @Test + public void whenSimpleDeserialize_thenCorrect() throws ParseException { + + final String jsonInput = "{\"imdbId\":\"tt0472043\",\"actors\":" + "[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"Tue Sep 21 11:00:00 GMT 1982\",\"filmography\":" + "[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}"; + + final Gson gson = new GsonBuilder().setDateFormat("EEE MMM dd hh:mm:ss zzz yyyy").create(); + + final Movie outputMovie = gson.fromJson(jsonInput, Movie.class); + + final String expectedOutput = "Movie [imdbId=tt0472043, director=null, actors=[ActorGson [imdbId=nm2199632, dateOfBirth=Tue Sep 21 11:00:00 GMT 1982, filmography=[Apocalypto, Beatdown, Wind Walkers]]]]"; + Assert.assertEquals(outputMovie.toString(), expectedOutput); + } + + @Test + public void whenCustomDeserialize_thenCorrect() throws ParseException { + + final String jsonInput = "{\"imdbId\":\"tt0472043\",\"actors\":" + "[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"1982-09-21T12:00:00+01:00\",\"filmography\":" + "[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}"; + + final Gson gson = new GsonBuilder().registerTypeAdapter(ActorGson.class, new ActorGsonDeserializer()).create(); + + final Movie outputMovie = gson.fromJson(jsonInput, Movie.class); + + final String expectedOutput = "Movie [imdbId=tt0472043, director=null, actors=[ActorGson [imdbId=nm2199632, dateOfBirth=Tue Sep 21 11:00:00 GMT 1982, filmography=[Apocalypto, Beatdown, Wind Walkers]]]]"; + Assert.assertEquals(outputMovie.toString(), expectedOutput); + } +} diff --git a/gson/src/test/java/org/baeldung/gson/serialization/GsonSerializeTest.java b/gson/src/test/java/org/baeldung/gson/serialization/GsonSerializeTest.java new file mode 100644 index 0000000000..7d5502b72f --- /dev/null +++ b/gson/src/test/java/org/baeldung/gson/serialization/GsonSerializeTest.java @@ -0,0 +1,48 @@ +package org.baeldung.gson.serialization; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParser; +import org.baeldung.gson.entities.ActorGson; +import org.baeldung.gson.entities.Movie; +import org.baeldung.gson.entities.MovieWithNullValue; +import org.junit.Assert; +import org.junit.Test; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; + +public class GsonSerializeTest { + + @Test + public void whenSimpleSerialize_thenCorrect() throws ParseException { + + SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); + + ActorGson rudyYoungblood = new ActorGson("nm2199632", sdf.parse("21-09-1982"), Arrays.asList("Apocalypto", "Beatdown", "Wind Walkers")); + Movie movie = new Movie("tt0472043", "Mel Gibson", Arrays.asList(rudyYoungblood)); + + String expectedOutput = "{\"imdbId\":\"tt0472043\",\"director\":\"Mel Gibson\",\"actors\":[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"Sep 21, 1982 12:00:00 AM\",\"filmography\":[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}"; + Assert.assertEquals(new Gson().toJson(movie), expectedOutput); + } + + @Test + public void whenCustomSerialize_thenCorrect() throws ParseException { + Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().serializeNulls().disableHtmlEscaping().registerTypeAdapter(ActorGson.class, new ActorGsonSerializer()).create(); + + SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); + + ActorGson rudyYoungblood = new ActorGson("nm2199632", sdf.parse("21-09-1982"), Arrays.asList("Apocalypto", "Beatdown", "Wind Walkers")); + MovieWithNullValue movieWithNullValue = new MovieWithNullValue(null, "Mel Gibson", Arrays.asList(rudyYoungblood)); + + String expectedOutput = new GsonBuilder() + .setPrettyPrinting() + .serializeNulls() + .disableHtmlEscaping() + .create() + .toJson(new JsonParser() + .parse("{\"imdbId\":null,\"actors\":[{\"IMDB Code\":\"nm2199632\",\"Date Of Birth\":\"21-09-1982\",\"N° Film: \":3,\"filmography\":\"Apocalypto-Beatdown-Wind Walkers\"}]}")); + Assert.assertEquals(gson.toJson(movieWithNullValue), expectedOutput); + } +} diff --git a/guava/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch b/guava/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch deleted file mode 100644 index 627021fb96..0000000000 --- a/guava/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/guava/.settings/.jsdtscope b/guava/.settings/.jsdtscope deleted file mode 100644 index 7b3f0c8b9f..0000000000 --- a/guava/.settings/.jsdtscope +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/guava/.settings/org.eclipse.jdt.core.prefs b/guava/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index b126d6476b..0000000000 --- a/guava/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,95 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=error -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=error -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/guava/.settings/org.eclipse.jdt.ui.prefs b/guava/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100644 index 471e9b0d81..0000000000 --- a/guava/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,55 +0,0 @@ -#Sat Jan 21 23:04:06 EET 2012 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=true -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=true -sp_cleanup.correct_indentation=true -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=true -sp_cleanup.make_local_variable_final=true -sp_cleanup.make_parameters_final=true -sp_cleanup.make_private_fields_final=false -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=true -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=false -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=true -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=true -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=true -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/guava/.settings/org.eclipse.m2e.core.prefs b/guava/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f1cb..0000000000 --- a/guava/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/guava/.settings/org.eclipse.m2e.wtp.prefs b/guava/.settings/org.eclipse.m2e.wtp.prefs deleted file mode 100644 index ef86089622..0000000000 --- a/guava/.settings/org.eclipse.m2e.wtp.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.m2e.wtp.enabledProjectSpecificPrefs=false diff --git a/guava/.settings/org.eclipse.wst.common.component b/guava/.settings/org.eclipse.wst.common.component deleted file mode 100644 index e98377cb0f..0000000000 --- a/guava/.settings/org.eclipse.wst.common.component +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/guava/.settings/org.eclipse.wst.common.project.facet.core.xml b/guava/.settings/org.eclipse.wst.common.project.facet.core.xml deleted file mode 100644 index f4ef8aa0a5..0000000000 --- a/guava/.settings/org.eclipse.wst.common.project.facet.core.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/guava/.settings/org.eclipse.wst.jsdt.ui.superType.container b/guava/.settings/org.eclipse.wst.jsdt.ui.superType.container deleted file mode 100644 index 3bd5d0a480..0000000000 --- a/guava/.settings/org.eclipse.wst.jsdt.ui.superType.container +++ /dev/null @@ -1 +0,0 @@ -org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/guava/.settings/org.eclipse.wst.jsdt.ui.superType.name b/guava/.settings/org.eclipse.wst.jsdt.ui.superType.name deleted file mode 100644 index 05bd71b6ec..0000000000 --- a/guava/.settings/org.eclipse.wst.jsdt.ui.superType.name +++ /dev/null @@ -1 +0,0 @@ -Window \ No newline at end of file diff --git a/guava/.settings/org.eclipse.wst.validation.prefs b/guava/.settings/org.eclipse.wst.validation.prefs deleted file mode 100644 index cacf5451ae..0000000000 --- a/guava/.settings/org.eclipse.wst.validation.prefs +++ /dev/null @@ -1,14 +0,0 @@ -DELEGATES_PREFERENCE=delegateValidatorList -USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator; -USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator; -USER_PREFERENCE=overrideGlobalPreferencestruedisableAllValidationfalseversion1.2.303.v201202090300 -eclipse.preferences.version=1 -override=true -suspend=false -vals/org.eclipse.jst.jsf.ui.JSFAppConfigValidator/global=FF01 -vals/org.eclipse.jst.jsp.core.JSPBatchValidator/global=FF01 -vals/org.eclipse.jst.jsp.core.JSPContentValidator/global=FF01 -vals/org.eclipse.jst.jsp.core.TLDValidator/global=FF01 -vals/org.eclipse.wst.dtd.core.dtdDTDValidator/global=FF01 -vals/org.eclipse.wst.jsdt.web.core.JsBatchValidator/global=TF02 -vf.version=3 diff --git a/guava/.settings/org.eclipse.wst.ws.service.policy.prefs b/guava/.settings/org.eclipse.wst.ws.service.policy.prefs deleted file mode 100644 index 9cfcabe16f..0000000000 --- a/guava/.settings/org.eclipse.wst.ws.service.policy.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.wst.ws.service.policy.projectEnabled=false diff --git a/guava/README.md b/guava/README.md index 28bcfeb912..40e7f19f41 100644 --- a/guava/README.md +++ b/guava/README.md @@ -15,3 +15,4 @@ - [Guava – Lists](http://www.baeldung.com/guava-lists) - [Guava – Sets](http://www.baeldung.com/guava-sets) - [Guava – Maps](http://www.baeldung.com/guava-maps) +- [Guava Set + Function = Map](http://www.baeldung.com/guava-set-function-map-tutorial) diff --git a/guava/src/test/java/org/baeldung/guava/GuavaMapFromSet.java b/guava/src/test/java/org/baeldung/guava/GuavaMapFromSet.java index 602205ff9f..1d19423f7e 100644 --- a/guava/src/test/java/org/baeldung/guava/GuavaMapFromSet.java +++ b/guava/src/test/java/org/baeldung/guava/GuavaMapFromSet.java @@ -11,91 +11,91 @@ import com.google.common.base.Function; public class GuavaMapFromSet extends AbstractMap { - private class SingleEntry implements Entry { - private K key; + private class SingleEntry implements Entry { + private K key; - public SingleEntry( K key) { - this.key = key; - } + public SingleEntry(K key) { + this.key = key; + } - @Override - public K getKey() { - return this.key; - } + @Override + public K getKey() { + return this.key; + } - @Override - public V getValue() { - V value = GuavaMapFromSet.this.cache.get(this.key); - if (value == null) { - value = GuavaMapFromSet.this.function.apply(this.key); - GuavaMapFromSet.this.cache.put(this.key, value); - } - return value; - } + @Override + public V getValue() { + V value = GuavaMapFromSet.this.cache.get(this.key); + if (value == null) { + value = GuavaMapFromSet.this.function.apply(this.key); + GuavaMapFromSet.this.cache.put(this.key, value); + } + return value; + } - @Override - public V setValue( V value) { - throw new UnsupportedOperationException(); - } - } + @Override + public V setValue(V value) { + throw new UnsupportedOperationException(); + } + } - private class MyEntrySet extends AbstractSet> { + private class MyEntrySet extends AbstractSet> { - public class EntryIterator implements Iterator> { - private Iterator inner; + public class EntryIterator implements Iterator> { + private Iterator inner; - public EntryIterator() { - this.inner = MyEntrySet.this.keys.iterator(); - } + public EntryIterator() { + this.inner = MyEntrySet.this.keys.iterator(); + } - @Override - public boolean hasNext() { - return this.inner.hasNext(); - } + @Override + public boolean hasNext() { + return this.inner.hasNext(); + } - @Override - public Map.Entry next() { - K key = this.inner.next(); - return new SingleEntry(key); - } + @Override + public Map.Entry next() { + K key = this.inner.next(); + return new SingleEntry(key); + } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - } + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } - private Set keys; + private Set keys; - public MyEntrySet( Set keys) { - this.keys = keys; - } + public MyEntrySet(Set keys) { + this.keys = keys; + } - @Override - public Iterator> iterator() { - return new EntryIterator(); - } + @Override + public Iterator> iterator() { + return new EntryIterator(); + } - @Override - public int size() { - return this.keys.size(); - } + @Override + public int size() { + return this.keys.size(); + } - } + } - private WeakHashMap cache; - private Set> entries; - private Function function; + private WeakHashMap cache; + private Set> entries; + private Function function; - public GuavaMapFromSet( Set keys, Function function) { - this.function = function; - this.cache = new WeakHashMap(); - this.entries = new MyEntrySet(keys); - } + public GuavaMapFromSet(Set keys, Function function) { + this.function = function; + this.cache = new WeakHashMap(); + this.entries = new MyEntrySet(keys); + } - @Override - public Set> entrySet() { - return this.entries; - } + @Override + public Set> entrySet() { + return this.entries; + } } diff --git a/guava/src/test/java/org/baeldung/guava/GuavaMapFromSetTests.java b/guava/src/test/java/org/baeldung/guava/GuavaMapFromSetTests.java index 9abb5d14a9..7dc4550c09 100644 --- a/guava/src/test/java/org/baeldung/guava/GuavaMapFromSetTests.java +++ b/guava/src/test/java/org/baeldung/guava/GuavaMapFromSetTests.java @@ -13,54 +13,52 @@ import com.google.common.base.Function; public class GuavaMapFromSetTests { - @Test - public void givenStringSet_whenMapsToElementLength_thenCorrect() { - Function function = new Function() { + @Test + public void givenStringSet_whenMapsToElementLength_thenCorrect() { + Function function = new Function() { + @Override + public String apply(Integer from) { + return Integer.toBinaryString(from); + } + }; + Set set = new TreeSet<>(Arrays.asList(32, 64, 128)); + Map map = new GuavaMapFromSet(set, function); + assertTrue(map.get(32).equals("100000") + && map.get(64).equals("1000000") + && map.get(128).equals("10000000")); + } - @Override - public String apply(Integer from) { - return Integer.toBinaryString(from.intValue()); - } - }; - Set set = (Set) new TreeSet(Arrays.asList( - 32, 64, 128)); - Map map = new GuavaMapFromSet(set, - function); - assertTrue(map.get(32).equals("100000") - && map.get(64).equals("1000000") - && map.get(128).equals("10000000")); - } + @Test + public void givenIntSet_whenMapsToElementBinaryValue_thenCorrect() { + Function function = new Function() { - @Test - public void givenIntSet_whenMapsToElementBinaryValue_thenCorrect() { - Function function = new Function() { + @Override + public Integer apply(String from) { + return from.length(); + } + }; + Set set = new TreeSet<>(Arrays.asList( + "four", "three", "twelve")); + Map map = new GuavaMapFromSet(set, + function); + assertTrue(map.get("four") == 4 && map.get("three") == 5 + && map.get("twelve") == 6); + } - @Override - public Integer apply(String from) { - return from.length(); - } - }; - Set set = (Set) new TreeSet(Arrays.asList( - "four", "three", "twelve")); - Map map = new GuavaMapFromSet(set, - function); - assertTrue(map.get("four") == 4 && map.get("three") == 5 - && map.get("twelve") == 6); - } - @Test - public void givenSet_whenNewSetElementAddedAndMappedLive_thenCorrect() { - Function function = new Function() { + @Test + public void givenSet_whenNewSetElementAddedAndMappedLive_thenCorrect() { + Function function = new Function() { - @Override - public Integer apply(String from) { - return from.length(); - } - }; - Set set = (Set) new TreeSet(Arrays.asList( - "four", "three", "twelve")); - Map map = new GuavaMapFromSet(set, - function); - set.add("one"); - assertTrue(map.get("one") == 3 && map.size()==4); - } + @Override + public Integer apply(String from) { + return from.length(); + } + }; + Set set = new TreeSet<>(Arrays.asList( + "four", "three", "twelve")); + Map map = new GuavaMapFromSet(set, + function); + set.add("one"); + assertTrue(map.get("one") == 3 && map.size() == 4); + } } diff --git a/guava/src/test/java/org/baeldung/hamcrest/README.md b/guava/src/test/java/org/baeldung/hamcrest/README.md new file mode 100644 index 0000000000..7266ecda3a --- /dev/null +++ b/guava/src/test/java/org/baeldung/hamcrest/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Testing with Hamcrest](http://www.baeldung.com/java-junit-hamcrest-guide) diff --git a/guava18/pom.xml b/guava18/pom.xml index 6002b37d74..413e9c35b8 100644 --- a/guava18/pom.xml +++ b/guava18/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung @@ -14,12 +13,15 @@ guava 18.0 + junit junit 4.12 + test + diff --git a/guava19/pom.xml b/guava19/pom.xml index 13f3b471f1..61fbf38575 100644 --- a/guava19/pom.xml +++ b/guava19/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 com.baeldung @@ -10,20 +11,23 @@ com.google.guava guava - 19.0 + ${guava.version} + junit junit 4.12 + test org.hamcrest hamcrest-all 1.3 + test - + @@ -42,4 +46,8 @@ + + 19.0 + + \ No newline at end of file diff --git a/handling-spring-static-resources/README.md b/handling-spring-static-resources/README.md new file mode 100644 index 0000000000..d8f64bc427 --- /dev/null +++ b/handling-spring-static-resources/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: +- [Cachable Static Assets with Spring MVC](http://www.baeldung.com/cachable-static-assets-with-spring-mvc) +- [Minification of JS and CSS Assets with Maven](http://www.baeldung.com/maven-minification-of-js-and-css-assets) diff --git a/handling-spring-static-resources/pom.xml b/handling-spring-static-resources/pom.xml index aca069e300..6dd0c95026 100644 --- a/handling-spring-static-resources/pom.xml +++ b/handling-spring-static-resources/pom.xml @@ -115,6 +115,7 @@ jackson-databind ${jackson.version} + org.hibernate hibernate-validator @@ -221,8 +222,7 @@ 1.9.2.RELEASE - - 2.7.2 + 2.7.8 1.7.13 diff --git a/hazelcast/pom.xml b/hazelcast/pom.xml new file mode 100644 index 0000000000..00960eadd2 --- /dev/null +++ b/hazelcast/pom.xml @@ -0,0 +1,77 @@ + + 4.0.0 + com.baeldung + hazelcast + 0.0.1-SNAPSHOT + hazelcast + + + + com.hazelcast + hazelcast + ${hazelcast.version} + + + + com.hazelcast + hazelcast-client + 3.7.2 + + + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + + ch.qos.logback + logback-classic + ${logback.version} + + + + ch.qos.logback + logback-core + ${logback.version} + + + + + + hazelcast + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + + + + + 3.7.2 + + + 1.7.21 + 1.1.7 + + + 3.5.1 + + + \ No newline at end of file diff --git a/hazelcast/src/main/java/com/baeldung/hazelcast/cluster/NativeClient.java b/hazelcast/src/main/java/com/baeldung/hazelcast/cluster/NativeClient.java new file mode 100644 index 0000000000..697e362289 --- /dev/null +++ b/hazelcast/src/main/java/com/baeldung/hazelcast/cluster/NativeClient.java @@ -0,0 +1,24 @@ +package com.baeldung.hazelcast.cluster; + +import java.util.Map.Entry; + +import com.hazelcast.client.HazelcastClient; +import com.hazelcast.client.config.ClientConfig; +import com.hazelcast.config.GroupConfig; +import com.hazelcast.core.HazelcastInstance; +import com.hazelcast.core.IMap; + +public class NativeClient { + + public static void main(String[] args) throws InterruptedException { + ClientConfig config = new ClientConfig(); + GroupConfig groupConfig = config.getGroupConfig(); + groupConfig.setName("dev"); + groupConfig.setPassword("dev-pass"); + HazelcastInstance hazelcastInstanceClient = HazelcastClient.newHazelcastClient(config); + IMap map = hazelcastInstanceClient.getMap("data"); + for (Entry entry : map.entrySet()) { + System.out.println(String.format("Key: %d, Value: %s", entry.getKey(), entry.getValue())); + } + } +} diff --git a/hazelcast/src/main/java/com/baeldung/hazelcast/cluster/ServerNode.java b/hazelcast/src/main/java/com/baeldung/hazelcast/cluster/ServerNode.java new file mode 100644 index 0000000000..36028834a4 --- /dev/null +++ b/hazelcast/src/main/java/com/baeldung/hazelcast/cluster/ServerNode.java @@ -0,0 +1,19 @@ +package com.baeldung.hazelcast.cluster; + +import java.util.Map; + +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import com.hazelcast.core.IdGenerator; + +public class ServerNode { + + public static void main(String[] args) { + HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance(); + Map map = hazelcastInstance.getMap("data"); + IdGenerator idGenerator = hazelcastInstance.getIdGenerator("newid"); + for (int i = 0; i < 10; i++) { + map.put(idGenerator.newId(), "message" + 1); + } + } +} diff --git a/hazelcast/src/main/resources/hazelcast.xml b/hazelcast/src/main/resources/hazelcast.xml new file mode 100644 index 0000000000..f29dc532b8 --- /dev/null +++ b/hazelcast/src/main/resources/hazelcast.xml @@ -0,0 +1,16 @@ + + + + 5701 + + + + + machine1 + localhost + + + + \ No newline at end of file diff --git a/hazelcast/src/main/resources/logback.xml b/hazelcast/src/main/resources/logback.xml new file mode 100644 index 0000000000..8b566286b8 --- /dev/null +++ b/hazelcast/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg %n + + + + + + + + + + + + \ No newline at end of file diff --git a/httpclient/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch b/httpclient/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch deleted file mode 100644 index 627021fb96..0000000000 --- a/httpclient/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/httpclient/.settings/.jsdtscope b/httpclient/.settings/.jsdtscope deleted file mode 100644 index 7b3f0c8b9f..0000000000 --- a/httpclient/.settings/.jsdtscope +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/httpclient/.settings/org.eclipse.jdt.core.prefs b/httpclient/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index b126d6476b..0000000000 --- a/httpclient/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,95 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=error -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=error -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/httpclient/.settings/org.eclipse.m2e.core.prefs b/httpclient/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f1cb..0000000000 --- a/httpclient/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/httpclient/.settings/org.eclipse.m2e.wtp.prefs b/httpclient/.settings/org.eclipse.m2e.wtp.prefs deleted file mode 100644 index ef86089622..0000000000 --- a/httpclient/.settings/org.eclipse.m2e.wtp.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.m2e.wtp.enabledProjectSpecificPrefs=false diff --git a/httpclient/.settings/org.eclipse.wst.common.component b/httpclient/.settings/org.eclipse.wst.common.component deleted file mode 100644 index e98377cb0f..0000000000 --- a/httpclient/.settings/org.eclipse.wst.common.component +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/httpclient/.settings/org.eclipse.wst.common.project.facet.core.xml b/httpclient/.settings/org.eclipse.wst.common.project.facet.core.xml deleted file mode 100644 index f4ef8aa0a5..0000000000 --- a/httpclient/.settings/org.eclipse.wst.common.project.facet.core.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/httpclient/.settings/org.eclipse.wst.jsdt.ui.superType.container b/httpclient/.settings/org.eclipse.wst.jsdt.ui.superType.container deleted file mode 100644 index 3bd5d0a480..0000000000 --- a/httpclient/.settings/org.eclipse.wst.jsdt.ui.superType.container +++ /dev/null @@ -1 +0,0 @@ -org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/httpclient/.settings/org.eclipse.wst.jsdt.ui.superType.name b/httpclient/.settings/org.eclipse.wst.jsdt.ui.superType.name deleted file mode 100644 index 05bd71b6ec..0000000000 --- a/httpclient/.settings/org.eclipse.wst.jsdt.ui.superType.name +++ /dev/null @@ -1 +0,0 @@ -Window \ No newline at end of file diff --git a/httpclient/.settings/org.eclipse.wst.validation.prefs b/httpclient/.settings/org.eclipse.wst.validation.prefs deleted file mode 100644 index cacf5451ae..0000000000 --- a/httpclient/.settings/org.eclipse.wst.validation.prefs +++ /dev/null @@ -1,14 +0,0 @@ -DELEGATES_PREFERENCE=delegateValidatorList -USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator; -USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator; -USER_PREFERENCE=overrideGlobalPreferencestruedisableAllValidationfalseversion1.2.303.v201202090300 -eclipse.preferences.version=1 -override=true -suspend=false -vals/org.eclipse.jst.jsf.ui.JSFAppConfigValidator/global=FF01 -vals/org.eclipse.jst.jsp.core.JSPBatchValidator/global=FF01 -vals/org.eclipse.jst.jsp.core.JSPContentValidator/global=FF01 -vals/org.eclipse.jst.jsp.core.TLDValidator/global=FF01 -vals/org.eclipse.wst.dtd.core.dtdDTDValidator/global=FF01 -vals/org.eclipse.wst.jsdt.web.core.JsBatchValidator/global=TF02 -vf.version=3 diff --git a/httpclient/.settings/org.eclipse.wst.ws.service.policy.prefs b/httpclient/.settings/org.eclipse.wst.ws.service.policy.prefs deleted file mode 100644 index 9cfcabe16f..0000000000 --- a/httpclient/.settings/org.eclipse.wst.ws.service.policy.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.wst.ws.service.policy.projectEnabled=false diff --git a/httpclient/pom.xml b/httpclient/pom.xml index 66b2076852..cac363c414 100644 --- a/httpclient/pom.xml +++ b/httpclient/pom.xml @@ -141,12 +141,52 @@ org.apache.maven.plugins maven-surefire-plugin ${maven-surefire-plugin.version} + + + **/*LiveTest.java + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*ManualTest.java + + + **/*LiveTest.java + + + + + + + json + + + + + + + + 4.3.11.Final diff --git a/httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientTest.java b/httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientLiveTest.java similarity index 99% rename from httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientTest.java rename to httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientLiveTest.java index 151ed10f37..b1399dcab8 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientLiveTest.java @@ -33,7 +33,7 @@ import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.junit.Test; -public class HttpAsyncClientTest { +public class HttpAsyncClientLiveTest { private static final String HOST = "http://www.google.com"; private static final String HOST_WITH_SSL = "https://mms.nw.ru/"; @@ -51,7 +51,7 @@ public class HttpAsyncClientTest { @Test public void whenUseHttpAsyncClient_thenCorrect() throws InterruptedException, ExecutionException, IOException { final CloseableHttpAsyncClient client = HttpAsyncClients.createDefault(); - // client.start(); + client.start(); final HttpGet request = new HttpGet(HOST); final Future future = client.execute(request, null); diff --git a/httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartTest.java b/httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartLiveTest.java similarity index 98% rename from httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartTest.java rename to httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartLiveTest.java index 371657af62..6fad126537 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/HttpClientMultipartLiveTest.java @@ -28,15 +28,17 @@ 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; -public class HttpClientMultipartTest { +@Ignore("Server is not available") +public class HttpClientMultipartLiveTest { private static final String SERVER = "http://echo.200please.com"; private static final String TEXTFILENAME = "temp.txt"; private static final String IMAGEFILENAME = "image.jpg"; private static final String ZIPFILENAME = "zipFile.zip"; - private static final Logger LOGGER = Logger.getLogger("org.baeldung.httpclient.HttpClientMultipartTest"); + private static final Logger LOGGER = Logger.getLogger("org.baeldung.httpclient.HttpClientMultipartLiveTest"); private CloseableHttpClient client; private HttpPost post; private BufferedReader rd; diff --git a/httpclient/src/test/java/org/baeldung/httpclient/HttpClientPostingTest.java b/httpclient/src/test/java/org/baeldung/httpclient/HttpClientPostingLiveTest.java similarity index 98% rename from httpclient/src/test/java/org/baeldung/httpclient/HttpClientPostingTest.java rename to httpclient/src/test/java/org/baeldung/httpclient/HttpClientPostingLiveTest.java index 7b75cdfc19..ada5667f0b 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/HttpClientPostingTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/HttpClientPostingLiveTest.java @@ -29,7 +29,10 @@ import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.junit.Test; -public class HttpClientPostingTest { +/* + * NOTE : Need module spring-rest to be running + */ +public class HttpClientPostingLiveTest { private static final String SAMPLE_URL = "http://localhost:8080/spring-rest/users"; private static final String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://browserspy.dk/password-ok.php"; private static final String DEFAULT_USER = "test"; diff --git a/httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java b/httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java index 952ce3af25..e9a16f18ad 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java @@ -1,24 +1,24 @@ package org.baeldung.httpclient; -import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; import java.io.IOException; import java.security.GeneralSecurityException; -import java.security.cert.X509Certificate; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; 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.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLContextBuilder; -import org.apache.http.conn.ssl.SSLContexts; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.conn.ssl.TrustStrategy; @@ -27,6 +27,8 @@ import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.ssl.SSLContexts; import org.junit.Test; /** @@ -42,7 +44,7 @@ public class HttpsClientSslLiveTest { // tests @Test(expected = SSLException.class) - public final void whenHttpsUrlIsConsumed_thenException() throws ClientProtocolException, IOException { + public final void whenHttpsUrlIsConsumed_thenException() throws IOException { final CloseableHttpClient httpClient = HttpClientBuilder.create().build(); final HttpGet getMethod = new HttpGet(HOST_WITH_SSL); @@ -53,12 +55,7 @@ public class HttpsClientSslLiveTest { @SuppressWarnings("deprecation") @Test public final void givenHttpClientPre4_3_whenAcceptingAllCertificates_thenCanConsumeHttpsUriWithSelfSignedCertificate() throws IOException, GeneralSecurityException { - final TrustStrategy acceptingTrustStrategy = new TrustStrategy() { - @Override - public final boolean isTrusted(final X509Certificate[] certificate, final String authType) { - return true; - } - }; + final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true; final SSLSocketFactory sf = new SSLSocketFactory(acceptingTrustStrategy, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); final SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("https", 443, sf)); @@ -75,12 +72,7 @@ public class HttpsClientSslLiveTest { @Test public final void givenHttpClientAfter4_3_whenAcceptingAllCertificates_thenCanConsumeHttpsUriWithSelfSignedCertificate() throws IOException, GeneralSecurityException { - final TrustStrategy acceptingTrustStrategy = new TrustStrategy() { - @Override - public final boolean isTrusted(final X509Certificate[] certificate, final String authType) { - return true; - } - }; + final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true; final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); @@ -108,4 +100,25 @@ public class HttpsClientSslLiveTest { assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); } + @Test + public final void givenIgnoringCertificates_whenHttpsUrlIsConsumed_thenCorrect() throws IOException { + + final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true; + + SSLContext sslContext = null; + try { + sslContext = new SSLContextBuilder().loadTrustMaterial(null, acceptingTrustStrategy).build(); + + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { + e.printStackTrace(); + } + + 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)); + } + } diff --git a/httpclient/src/test/java/org/baeldung/httpclient/SandboxTest.java b/httpclient/src/test/java/org/baeldung/httpclient/SandboxTest.java deleted file mode 100644 index dc1a206f0d..0000000000 --- a/httpclient/src/test/java/org/baeldung/httpclient/SandboxTest.java +++ /dev/null @@ -1,188 +0,0 @@ -package org.baeldung.httpclient; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; - -import org.apache.http.Header; -import org.apache.http.HttpHost; -import org.apache.http.HttpResponse; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.AuthenticationException; -import org.apache.http.auth.MalformedChallengeException; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.AuthCache; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.CookieStore; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.impl.auth.DigestScheme; -import org.apache.http.impl.client.BasicAuthCache; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.impl.cookie.BasicClientCookie; -import org.apache.http.util.EntityUtils; -import org.junit.Ignore; -import org.junit.Test; - -public class SandboxTest { - - // original example - @Ignore - @Test - public final void whenInterestingDigestAuthScenario_then401UnAuthorized() throws AuthenticationException, ClientProtocolException, IOException, MalformedChallengeException { - final HttpHost targetHost = new HttpHost("httpbin.org", 80, "http"); - - // set up the credentials to run agains the server - final CredentialsProvider credsProvider = new BasicCredentialsProvider(); - credsProvider.setCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()), new UsernamePasswordCredentials("user", "passwd")); - - // We need a first run to get a 401 to seed the digest auth - - // Make a client using those creds - final CloseableHttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build(); - - // And make a call to the URL we are after - final HttpGet httpget = new HttpGet("http://httpbin.org/digest-auth/auth/user/passwd"); - - // Create a context to use - final HttpClientContext context = HttpClientContext.create(); - - // Get a response from the sever (expect a 401!) - final HttpResponse authResponse = client.execute(targetHost, httpget, context); - - // Pull out the auth header that came back from the server - final Header challenge = authResponse.getHeaders("WWW-Authenticate")[0]; - - // Lets use a digest scheme to solve it - final DigestScheme digest = new DigestScheme(); - digest.processChallenge(challenge); - - // Make a header with the solution based upon user/password and what the digest got out of the initial 401 reponse - final Header solution = digest.authenticate(new UsernamePasswordCredentials("user", "passwd"), httpget, context); - - // Need an auth cache to use the new digest we made - final AuthCache authCache = new BasicAuthCache(); - authCache.put(targetHost, digest); - - // Add the authCache and thus solved digest to the context - context.setAuthCache(authCache); - - // Pimp up our http get with the solved header made by the digest - httpget.addHeader(solution); - - // use it! - System.out.println("Executing request " + httpget.getRequestLine() + " to target " + targetHost); - - for (int i = 0; i < 3; i++) { - final CloseableHttpResponse responseGood = client.execute(targetHost, httpget, context); - - try { - System.out.println("----------------------------------------"); - System.out.println(responseGood.getStatusLine()); - System.out.println(EntityUtils.toString(responseGood.getEntity())); - } finally { - responseGood.close(); - } - } - } - - @Test - public final void whenInterestingDigestAuthScenario_then200OK() throws AuthenticationException, ClientProtocolException, IOException, MalformedChallengeException { - final HttpHost targetHost = new HttpHost("httpbin.org", 80, "http"); - - // set up the credentials to run agains the server - final CredentialsProvider credsProvider = new BasicCredentialsProvider(); - credsProvider.setCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()), new UsernamePasswordCredentials("user", "passwd")); - - // This endpoint need fake cookie to work properly - final CookieStore cookieStore = new BasicCookieStore(); - final BasicClientCookie cookie = new BasicClientCookie("fake", "fake_value"); - cookie.setDomain("httpbin.org"); - cookie.setPath("/"); - cookieStore.addCookie(cookie); - - // Make a client using those creds - final CloseableHttpClient client = HttpClients.custom().setDefaultCookieStore(cookieStore).setDefaultCredentialsProvider(credsProvider).build(); - - // And make a call to the URL we are after - final HttpGet httpget = new HttpGet("http://httpbin.org/digest-auth/auth/user/passwd"); - - // Create a context to use - final HttpClientContext context = HttpClientContext.create(); - - // Get a response from the sever (401 implicitly) - final HttpResponse authResponse = client.execute(targetHost, httpget, context); - assertEquals(200, authResponse.getStatusLine().getStatusCode()); - - // HttpClient will use cached digest parameters for future requests - System.out.println("Executing request " + httpget.getRequestLine() + " to target " + targetHost); - - for (int i = 0; i < 3; i++) { - final CloseableHttpResponse responseGood = client.execute(targetHost, httpget, context); - - try { - System.out.println("----------------------------------------"); - System.out.println(responseGood.getStatusLine()); - assertEquals(200, responseGood.getStatusLine().getStatusCode()); - } finally { - responseGood.close(); - } - } - client.close(); - } - - // This test needs module spring-security-rest-digest-auth to be running - @Test - public final void whenWeKnowDigestParameters_thenNo401Status() throws AuthenticationException, ClientProtocolException, IOException, MalformedChallengeException { - final HttpHost targetHost = new HttpHost("localhost", 8080, "http"); - - final CredentialsProvider credsProvider = new BasicCredentialsProvider(); - credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("user1", "user1Pass")); - - final CloseableHttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build(); - - final HttpGet httpget = new HttpGet("http://localhost:8080/spring-security-rest-digest-auth/api/foos/1"); - - final HttpClientContext context = HttpClientContext.create(); - // == make it preemptive - final AuthCache authCache = new BasicAuthCache(); - final DigestScheme digestAuth = new DigestScheme(); - digestAuth.overrideParamter("realm", "Custom Realm Name"); - digestAuth.overrideParamter("nonce", "nonce value goes here"); - authCache.put(targetHost, digestAuth); - context.setAuthCache(authCache); - // == end - System.out.println("Executing The Request knowing the digest parameters ==== "); - final HttpResponse authResponse = client.execute(targetHost, httpget, context); - assertEquals(200, authResponse.getStatusLine().getStatusCode()); - client.close(); - } - - // This test needs module spring-security-rest-digest-auth to be running - @Test - public final void whenDoNotKnowParameters_thenOnlyOne401() throws AuthenticationException, ClientProtocolException, IOException, MalformedChallengeException { - final HttpClientContext context = HttpClientContext.create(); - final HttpHost targetHost = new HttpHost("localhost", 8080, "http"); - final CredentialsProvider credsProvider = new BasicCredentialsProvider(); - credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("user1", "user1Pass")); - final CloseableHttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build(); - - final HttpGet httpget = new HttpGet("http://localhost:8080/spring-security-rest-digest-auth/api/foos/1"); - System.out.println("Executing The Request NOT knowing the digest parameters ==== "); - final HttpResponse tempResponse = client.execute(targetHost, httpget, context); - assertEquals(200, tempResponse.getStatusLine().getStatusCode()); - - for (int i = 0; i < 3; i++) { - System.out.println("No more Challenges or 401"); - final CloseableHttpResponse authResponse = client.execute(targetHost, httpget, context); - assertEquals(200, authResponse.getStatusLine().getStatusCode()); - authResponse.close(); - } - client.close(); - } -} diff --git a/httpclient/src/test/java/org/baeldung/httpclient/base/HttpClientLiveTest.java b/httpclient/src/test/java/org/baeldung/httpclient/base/HttpClientLiveTest.java index 23c1fdf430..878d220f67 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/base/HttpClientLiveTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/base/HttpClientLiveTest.java @@ -1,16 +1,8 @@ package org.baeldung.httpclient.base; -import static org.hamcrest.Matchers.emptyArray; -import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertThat; - -import java.io.IOException; -import java.io.InputStream; - import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpHeaders; -import org.apache.http.client.ClientProtocolException; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; @@ -23,6 +15,13 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import java.io.IOException; +import java.io.InputStream; + +import static org.hamcrest.Matchers.emptyArray; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertThat; + public class HttpClientLiveTest { private static final String SAMPLE_URL = "http://www.github.com"; @@ -56,7 +55,7 @@ public class HttpClientLiveTest { // tests @Test(expected = ConnectTimeoutException.class) - public final void givenLowTimeout_whenExecutingRequestWithTimeout_thenException() throws ClientProtocolException, IOException { + public final void givenLowTimeout_whenExecutingRequestWithTimeout_thenException() throws IOException { final RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(50).setConnectTimeout(50).setSocketTimeout(20).build(); final HttpGet request = new HttpGet(SAMPLE_URL); request.setConfig(requestConfig); @@ -66,20 +65,20 @@ public class HttpClientLiveTest { // tests - configs @Test - public final void givenHttpClientIsConfiguredWithCustomConnectionManager_whenExecutingRequest_thenNoExceptions() throws ClientProtocolException, IOException { + public final void givenHttpClientIsConfiguredWithCustomConnectionManager_whenExecutingRequest_thenNoExceptions() throws IOException { instance = HttpClientBuilder.create().setConnectionManager(new BasicHttpClientConnectionManager()).build(); response = instance.execute(new HttpGet(SAMPLE_URL)); } @Test - public final void givenCustomHeaderIsSet_whenSendingRequest_thenNoExceptions() throws ClientProtocolException, IOException { + public final void givenCustomHeaderIsSet_whenSendingRequest_thenNoExceptions() throws IOException { final HttpGet request = new HttpGet(SAMPLE_URL); request.addHeader(HttpHeaders.ACCEPT, "application/xml"); response = instance.execute(request); } @Test - public final void givenRequestWasSet_whenAnalyzingTheHeadersOfTheResponse_thenCorrect() throws ClientProtocolException, IOException { + public final void givenRequestWasSet_whenAnalyzingTheHeadersOfTheResponse_thenCorrect() throws IOException { response = instance.execute(new HttpGet(SAMPLE_URL)); final Header[] headers = response.getHeaders(HttpHeaders.CONTENT_TYPE); @@ -89,7 +88,7 @@ public class HttpClientLiveTest { // tests - cancel request @Test - public final void whenRequestIsCanceled_thenCorrect() throws ClientProtocolException, IOException { + public final void whenRequestIsCanceled_thenCorrect() throws IOException { instance = HttpClients.custom().build(); final HttpGet request = new HttpGet(SAMPLE_URL); response = instance.execute(request); diff --git a/httpclient/src/test/java/org/baeldung/httpclient/base/HttpClientSandboxLiveTest.java b/httpclient/src/test/java/org/baeldung/httpclient/base/HttpClientSandboxLiveTest.java index ff2f1cd194..40216a70a5 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/base/HttpClientSandboxLiveTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/base/HttpClientSandboxLiveTest.java @@ -6,27 +6,31 @@ import java.io.InputStream; import org.apache.http.HttpEntity; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; -import org.junit.After; import org.junit.Test; +/* + * NOTE : Need module spring-security-rest-basic-auth to be running + */ public class HttpClientSandboxLiveTest { - private CloseableHttpClient client; + @Test + public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectStatusCode() throws IOException { + final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + final AuthScope authscp = new AuthScope("localhost", 8080); + credentialsProvider.setCredentials(authscp, new UsernamePasswordCredentials("user1", "user1Pass")); - private CloseableHttpResponse response; + final CloseableHttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(credentialsProvider).build(); - @After - public final void after() throws IllegalStateException, IOException { - if (response == null) { - return; - } + final HttpGet httpGet = new HttpGet("http://localhost:8080/spring-security-rest-basic-auth/api/foos/1"); + final CloseableHttpResponse response = client.execute(httpGet); + + System.out.println(response.getStatusLine()); try { final HttpEntity entity = response.getEntity(); @@ -39,23 +43,4 @@ public class HttpClientSandboxLiveTest { response.close(); } } - - // tests - - // simple request - response - - @Test - public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectStatusCode() throws ClientProtocolException, IOException { - final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); - final AuthScope authscp = new AuthScope("localhost", 8080); - credentialsProvider.setCredentials(authscp, new UsernamePasswordCredentials("user1", "user1Pass")); - - client = HttpClientBuilder.create().setDefaultCredentialsProvider(credentialsProvider).build(); - - final HttpGet httpGet = new HttpGet("http://localhost:8080/spring-security-rest-basic-auth/api/foos/1"); - response = client.execute(httpGet); - - System.out.println(response.getStatusLine()); - } - } diff --git a/httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementTest.java b/httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java similarity index 99% rename from httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementTest.java rename to httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java index c5c960f527..e9db8c1e16 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java @@ -36,7 +36,7 @@ import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -public class HttpClientConnectionManagementTest { +public class HttpClientConnectionManagementLiveTest { private static final String SERVER1 = "http://www.petrikainulainen.net/"; private static final String SERVER7 = "http://www.baeldung.com/"; diff --git a/httpclient/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java b/httpclient/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java index 495d46e91f..e98dd4d14f 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java @@ -30,6 +30,10 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +/* + * NOTE : Need module spring-security-rest-basic-auth to be running + */ + public class HttpClientAuthLiveTest { private static final String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://localhost:8081/spring-security-rest-basic-auth/api/foos/1"; diff --git a/hystrix/.gitignore b/hystrix/.gitignore new file mode 100644 index 0000000000..b092c8122f --- /dev/null +++ b/hystrix/.gitignore @@ -0,0 +1,12 @@ +*.class + +#folders# +/target +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear +*.iml \ No newline at end of file diff --git a/hystrix/README.md b/hystrix/README.md new file mode 100644 index 0000000000..cc5c8a197f --- /dev/null +++ b/hystrix/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: +- [Hystrix Integration with Existing Spring Application](http://www.baeldung.com/hystrix-integration-with-spring-aop) +- [Introduction to Hystrix](http://www.baeldung.com/introduction-to-hystrix) diff --git a/hystrix/pom.xml b/hystrix/pom.xml index 0ec5fa0411..54c17f1487 100644 --- a/hystrix/pom.xml +++ b/hystrix/pom.xml @@ -6,16 +6,22 @@ com.baeldung hystrix 1.0 - hystrix + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + 1.8 - 1.4.10 + 1.5.4 0.20.7 @@ -27,41 +33,76 @@ 2.6 2.19.1 2.7 - + 1.3.16 + 1.4.3 + 1.4.0.RELEASE - + + org.springframework.boot + spring-boot-starter-tomcat + provided + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-aop + com.netflix.hystrix hystrix-core ${hystrix-core.version} - + + com.netflix.hystrix + hystrix-metrics-event-stream + ${hystrix-metrics-event-stream.version} + + com.netflix.rxjava rxjava-core ${rxjava-core.version} - org.hamcrest hamcrest-all ${hamcrest-all.version} test - junit junit ${junit.version} test - + + org.springframework + spring-test + test + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot-starter-test.version} + test + + + org.springframework.boot + spring-boot-maven-plugin + org.apache.maven.plugins maven-compiler-plugin @@ -71,9 +112,54 @@ 1.8 + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + **/*IntegrationTest.java + **/*LiveTest.java + + + - - + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + diff --git a/hystrix/src/main/java/com/baeldung/hystrix/AppConfig.java b/hystrix/src/main/java/com/baeldung/hystrix/AppConfig.java new file mode 100644 index 0000000000..8b11ac99c3 --- /dev/null +++ b/hystrix/src/main/java/com/baeldung/hystrix/AppConfig.java @@ -0,0 +1,20 @@ +package com.baeldung.hystrix; + +import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class AppConfig { + + public static void main(String[] args) { + SpringApplication.run(AppConfig.class, args); + } + + @Bean + public ServletRegistrationBean adminServletRegistrationBean() { + return new ServletRegistrationBean(new HystrixMetricsStreamServlet(), "/hystrix.stream"); + } +} diff --git a/hystrix/src/test/java/com/baeldung/hystrix/CommandHelloWorld.java b/hystrix/src/main/java/com/baeldung/hystrix/CommandHelloWorld.java similarity index 100% rename from hystrix/src/test/java/com/baeldung/hystrix/CommandHelloWorld.java rename to hystrix/src/main/java/com/baeldung/hystrix/CommandHelloWorld.java diff --git a/hystrix/src/main/java/com/baeldung/hystrix/HystrixAspect.java b/hystrix/src/main/java/com/baeldung/hystrix/HystrixAspect.java new file mode 100644 index 0000000000..3a650c2f4f --- /dev/null +++ b/hystrix/src/main/java/com/baeldung/hystrix/HystrixAspect.java @@ -0,0 +1,83 @@ +package com.baeldung.hystrix; + +import com.netflix.hystrix.*; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +@Component +@Aspect +public class HystrixAspect { + + private HystrixCommand.Setter config; + private HystrixCommandProperties.Setter commandProperties; + private HystrixThreadPoolProperties.Setter threadPoolProperties; + + @Value("${remoteservice.command.execution.timeout}") + private int executionTimeout; + + @Value("${remoteservice.command.sleepwindow}") + private int sleepWindow; + + @Value("${remoteservice.command.threadpool.maxsize}") + private int maxThreadCount; + + @Value("${remoteservice.command.threadpool.coresize}") + private int coreThreadCount; + + @Value("${remoteservice.command.task.queue.size}") + private int queueCount; + + @Value("${remoteservice.command.group.key}") + private String groupKey; + + @Value("${remoteservice.command.key}") + private String key; + + + @Around("@annotation(com.baeldung.hystrix.HystrixCircuitBreaker)") + public Object circuitBreakerAround(final ProceedingJoinPoint aJoinPoint) { + return new RemoteServiceCommand(config, aJoinPoint).execute(); + } + + @PostConstruct + private void setup() { + this.config = HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey)); + this.config = config.andCommandKey(HystrixCommandKey.Factory.asKey(key)); + + this.commandProperties = HystrixCommandProperties.Setter(); + this.commandProperties.withExecutionTimeoutInMilliseconds(executionTimeout); + this.commandProperties.withCircuitBreakerSleepWindowInMilliseconds(sleepWindow); + + this.threadPoolProperties = HystrixThreadPoolProperties.Setter(); + this.threadPoolProperties.withMaxQueueSize(maxThreadCount).withCoreSize(coreThreadCount).withMaxQueueSize(queueCount); + + this.config.andCommandPropertiesDefaults(commandProperties); + this.config.andThreadPoolPropertiesDefaults(threadPoolProperties); + } + + private static class RemoteServiceCommand extends HystrixCommand { + + private final ProceedingJoinPoint joinPoint; + + RemoteServiceCommand(final Setter config, final ProceedingJoinPoint joinPoint) { + super(config); + this.joinPoint = joinPoint; + } + + @Override + protected String run() throws Exception { + try { + return (String) joinPoint.proceed(); + } catch (final Throwable th) { + throw new Exception(th); + } + + } + } + +} diff --git a/hystrix/src/main/java/com/baeldung/hystrix/HystrixCircuitBreaker.java b/hystrix/src/main/java/com/baeldung/hystrix/HystrixCircuitBreaker.java new file mode 100644 index 0000000000..e7c0694a7b --- /dev/null +++ b/hystrix/src/main/java/com/baeldung/hystrix/HystrixCircuitBreaker.java @@ -0,0 +1,11 @@ +package com.baeldung.hystrix; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface HystrixCircuitBreaker { +} diff --git a/hystrix/src/main/java/com/baeldung/hystrix/HystrixController.java b/hystrix/src/main/java/com/baeldung/hystrix/HystrixController.java new file mode 100644 index 0000000000..69d9e30ff8 --- /dev/null +++ b/hystrix/src/main/java/com/baeldung/hystrix/HystrixController.java @@ -0,0 +1,22 @@ +package com.baeldung.hystrix; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HystrixController { + + @Autowired + private SpringExistingClient client; + + @RequestMapping("/withHystrix") + public String withHystrix() throws InterruptedException{ + return client.invokeRemoteServiceWithHystrix(); + } + + @RequestMapping("/withOutHystrix") + public String withOutHystrix() throws InterruptedException{ + return client.invokeRemoteServiceWithOutHystrix(); + } +} diff --git a/hystrix/src/test/java/com/baeldung/hystrix/RemoteServiceTestCommand.java b/hystrix/src/main/java/com/baeldung/hystrix/RemoteServiceTestCommand.java similarity index 100% rename from hystrix/src/test/java/com/baeldung/hystrix/RemoteServiceTestCommand.java rename to hystrix/src/main/java/com/baeldung/hystrix/RemoteServiceTestCommand.java diff --git a/hystrix/src/test/java/com/baeldung/hystrix/RemoteServiceTestSimulator.java b/hystrix/src/main/java/com/baeldung/hystrix/RemoteServiceTestSimulator.java similarity index 86% rename from hystrix/src/test/java/com/baeldung/hystrix/RemoteServiceTestSimulator.java rename to hystrix/src/main/java/com/baeldung/hystrix/RemoteServiceTestSimulator.java index 54c626a67a..d302166ea8 100644 --- a/hystrix/src/test/java/com/baeldung/hystrix/RemoteServiceTestSimulator.java +++ b/hystrix/src/main/java/com/baeldung/hystrix/RemoteServiceTestSimulator.java @@ -1,7 +1,7 @@ package com.baeldung.hystrix; -class RemoteServiceTestSimulator { +public class RemoteServiceTestSimulator { private long wait; diff --git a/hystrix/src/main/java/com/baeldung/hystrix/SpringExistingClient.java b/hystrix/src/main/java/com/baeldung/hystrix/SpringExistingClient.java new file mode 100644 index 0000000000..525c7b4785 --- /dev/null +++ b/hystrix/src/main/java/com/baeldung/hystrix/SpringExistingClient.java @@ -0,0 +1,20 @@ +package com.baeldung.hystrix; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component("springClient") +public class SpringExistingClient { + + @Value("${remoteservice.timeout}") + private int remoteServiceDelay; + + @HystrixCircuitBreaker + public String invokeRemoteServiceWithHystrix() throws InterruptedException{ + return new RemoteServiceTestSimulator(remoteServiceDelay).execute(); + } + + public String invokeRemoteServiceWithOutHystrix() throws InterruptedException{ + return new RemoteServiceTestSimulator(remoteServiceDelay).execute(); + } +} diff --git a/hystrix/src/main/resources/application.properties b/hystrix/src/main/resources/application.properties new file mode 100644 index 0000000000..50c241d03f --- /dev/null +++ b/hystrix/src/main/resources/application.properties @@ -0,0 +1,8 @@ +remoteservice.command.group.key=RemoteServiceGroup +remoteservice.command.key=RemoteServiceKey +remoteservice.command.execution.timeout=10000 +remoteservice.command.threadpool.coresize=5 +remoteservice.command.threadpool.maxsize=10 +remoteservice.command.task.queue.size=5 +remoteservice.command.sleepwindow=5000 +remoteservice.timeout=15000 \ No newline at end of file diff --git a/hystrix/src/test/java/com/baeldung/hystrix/HystrixTimeoutTest.java b/hystrix/src/test/java/com/baeldung/hystrix/HystrixTimeoutTest.java index 773c76536f..d72895aab9 100644 --- a/hystrix/src/test/java/com/baeldung/hystrix/HystrixTimeoutTest.java +++ b/hystrix/src/test/java/com/baeldung/hystrix/HystrixTimeoutTest.java @@ -1,62 +1,132 @@ package com.baeldung.hystrix; -import com.netflix.hystrix.*; -import com.netflix.hystrix.collapser.RequestCollapserFactory; +import com.netflix.hystrix.HystrixCommand; +import com.netflix.hystrix.HystrixCommandGroupKey; +import com.netflix.hystrix.HystrixCommandProperties; +import com.netflix.hystrix.HystrixThreadPoolProperties; import com.netflix.hystrix.exception.HystrixRuntimeException; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; public class HystrixTimeoutTest { - private static HystrixCommand.Setter config; - private static HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter(); - - - @Rule - public final ExpectedException exception = ExpectedException.none(); - - @Before - public void setup() { - config = HystrixCommand - .Setter - .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroup1")); - } - @Test - public void givenInputBob_andDefaultSettings_thenReturnHelloBob(){ + public void givenInputBobAndDefaultSettings_whenCommandExecuted_thenReturnHelloBob(){ assertThat(new CommandHelloWorld("Bob").execute(), equalTo("Hello Bob!")); } @Test - public void givenTimeoutEqualTo100_andDefaultSettings_thenReturnSuccess() throws InterruptedException { - assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(100)).execute(), equalTo("Success")); + public void givenSvcTimeoutOf100AndDefaultSettings_whenRemoteSvcExecuted_thenReturnSuccess() + throws InterruptedException { + HystrixCommand.Setter config = HystrixCommand + .Setter + .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroup2")); + + assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(100)).execute(), + equalTo("Success")); } - @Test - public void givenTimeoutEqualTo10000_andDefaultSettings_thenExpectHystrixRuntimeException() throws InterruptedException { - exception.expect(HystrixRuntimeException.class); + @Test(expected = HystrixRuntimeException.class) + public void givenSvcTimeoutOf10000AndDefaultSettings__whenRemoteSvcExecuted_thenExpectHRE() throws InterruptedException { + HystrixCommand.Setter config = HystrixCommand + .Setter + .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupTest3")); new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(10_000)).execute(); } @Test - public void givenTimeoutEqualTo5000_andExecutionTimeoutEqualTo10000_thenReturnSuccess() throws InterruptedException { + public void givenSvcTimeoutOf5000AndExecTimeoutOf10000_whenRemoteSvcExecuted_thenReturnSuccess() + throws InterruptedException { + + HystrixCommand.Setter config = HystrixCommand + .Setter + .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupTest4")); + HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter(); commandProperties.withExecutionTimeoutInMilliseconds(10_000); config.andCommandPropertiesDefaults(commandProperties); - assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(5_000)).execute(), equalTo("Success")); + + assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(), + equalTo("Success")); } - @Test - public void givenTimeoutEqualTo15000_andExecutionTimeoutEqualTo10000_thenExpectHystrixRuntimeException() throws InterruptedException { - exception.expect(HystrixRuntimeException.class); - commandProperties.withExecutionTimeoutInMilliseconds(10_000); + @Test(expected = HystrixRuntimeException.class) + public void givenSvcTimeoutOf15000AndExecTimeoutOf5000__whenExecuted_thenExpectHRE() + throws InterruptedException { + HystrixCommand.Setter config = HystrixCommand + .Setter + .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupTest5")); + HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter(); + commandProperties.withExecutionTimeoutInMilliseconds(5_000); config.andCommandPropertiesDefaults(commandProperties); new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(15_000)).execute(); } + @Test + public void givenSvcTimeoutOf500AndExecTimeoutOf10000AndThreadPool__whenExecuted_thenReturnSuccess() + throws InterruptedException { + + HystrixCommand.Setter config = HystrixCommand + .Setter + .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupThreadPool")); + HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter(); + commandProperties.withExecutionTimeoutInMilliseconds(10_000); + config.andCommandPropertiesDefaults(commandProperties); + config.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter() + .withMaxQueueSize(10) + .withCoreSize(3) + .withQueueSizeRejectionThreshold(10)); + + assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(), + equalTo("Success")); + } + + @Test + public void givenCircuitBreakerSetup__whenRemoteSvcCmdExecuted_thenReturnSuccess() + throws InterruptedException { + + HystrixCommand.Setter config = HystrixCommand + .Setter + .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupCircuitBreaker")); + HystrixCommandProperties.Setter properties = HystrixCommandProperties.Setter(); + properties.withExecutionTimeoutInMilliseconds(1000); + + properties.withCircuitBreakerSleepWindowInMilliseconds(4000); + properties.withExecutionIsolationStrategy( + HystrixCommandProperties.ExecutionIsolationStrategy.THREAD); + properties.withCircuitBreakerEnabled(true); + properties.withCircuitBreakerRequestVolumeThreshold(1); + + config.andCommandPropertiesDefaults(properties); + + config.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter() + .withMaxQueueSize(1) + .withCoreSize(1) + .withQueueSizeRejectionThreshold(1)); + + assertThat(this.invokeRemoteService(config, 10_000), equalTo(null)); + assertThat(this.invokeRemoteService(config, 10_000), equalTo(null)); + assertThat(this.invokeRemoteService(config, 10_000), equalTo(null)); + Thread.sleep(5000); + + assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(), + equalTo("Success")); + assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(), + equalTo("Success")); + assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(), + equalTo("Success")); + } + + public String invokeRemoteService(HystrixCommand.Setter config, int timeout) + throws InterruptedException { + String response = null; + try { + response = new RemoteServiceTestCommand(config, + new RemoteServiceTestSimulator(timeout)).execute(); + } catch (HystrixRuntimeException ex) { + System.out.println("ex = " + ex); + } + return response; + } } diff --git a/hystrix/src/test/java/com/baeldung/hystrix/SpringAndHystrixIntegrationTest.java b/hystrix/src/test/java/com/baeldung/hystrix/SpringAndHystrixIntegrationTest.java new file mode 100644 index 0000000000..004314b0ed --- /dev/null +++ b/hystrix/src/test/java/com/baeldung/hystrix/SpringAndHystrixIntegrationTest.java @@ -0,0 +1,36 @@ +package com.baeldung.hystrix; + +import com.netflix.hystrix.exception.HystrixRuntimeException; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = AppConfig.class) +public class SpringAndHystrixIntegrationTest { + + @Autowired + private HystrixController hystrixController; + + @Rule + public final ExpectedException exception = ExpectedException.none(); + + @Test + public void givenTimeOutOf15000_whenClientCalledWithHystrix_thenExpectHystrixRuntimeException() throws InterruptedException { + exception.expect(HystrixRuntimeException.class); + hystrixController.withHystrix(); + } + + @Test + public void givenTimeOutOf15000_whenClientCalledWithOutHystrix_thenExpectSuccess() throws InterruptedException { + assertThat(hystrixController.withOutHystrix(), equalTo("Success")); + } + +} diff --git a/immutables/README.md b/immutables/README.md new file mode 100644 index 0000000000..b69a14f035 --- /dev/null +++ b/immutables/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Introduction to Immutables](http://www.baeldung.com/immutables) diff --git a/immutables/pom.xml b/immutables/pom.xml new file mode 100644 index 0000000000..2b4aba59b1 --- /dev/null +++ b/immutables/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + com.baeldung + immutables + 1.0.0-SNAPSHOT + + + + org.immutables + value + 2.2.10 + + + junit + junit + 4.12 + test + + + org.assertj + assertj-core + 3.5.2 + test + + + org.mutabilitydetector + MutabilityDetector + 0.9.5 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/immutables/src/main/java/com/baeldung/immutable/Address.java b/immutables/src/main/java/com/baeldung/immutable/Address.java new file mode 100644 index 0000000000..93474dc043 --- /dev/null +++ b/immutables/src/main/java/com/baeldung/immutable/Address.java @@ -0,0 +1,9 @@ +package com.baeldung.immutable; + +import org.immutables.value.Value; + +@Value.Immutable +public interface Address { + String getStreetName(); + Integer getNumber(); +} diff --git a/immutables/src/main/java/com/baeldung/immutable/Person.java b/immutables/src/main/java/com/baeldung/immutable/Person.java new file mode 100644 index 0000000000..466daf42c2 --- /dev/null +++ b/immutables/src/main/java/com/baeldung/immutable/Person.java @@ -0,0 +1,9 @@ +package com.baeldung.immutable; + +import org.immutables.value.Value; + +@Value.Immutable +public abstract class Person { + abstract String getName(); + abstract Integer getAge(); +} diff --git a/immutables/src/main/java/com/baeldung/immutable/auxiliary/Person.java b/immutables/src/main/java/com/baeldung/immutable/auxiliary/Person.java new file mode 100644 index 0000000000..78fe28c50c --- /dev/null +++ b/immutables/src/main/java/com/baeldung/immutable/auxiliary/Person.java @@ -0,0 +1,13 @@ +package com.baeldung.immutable.auxiliary; + + +import org.immutables.value.Value; + +@Value.Immutable +public abstract class Person { + abstract String getName(); + abstract Integer getAge(); + + @Value.Auxiliary + abstract String getAuxiliaryField(); +} \ No newline at end of file diff --git a/immutables/src/main/java/com/baeldung/immutable/default_/Person.java b/immutables/src/main/java/com/baeldung/immutable/default_/Person.java new file mode 100644 index 0000000000..bc48f11a38 --- /dev/null +++ b/immutables/src/main/java/com/baeldung/immutable/default_/Person.java @@ -0,0 +1,14 @@ +package com.baeldung.immutable.default_; + +import org.immutables.value.Value; + +@Value.Immutable(prehash = true) +public abstract class Person { + + abstract String getName(); + + @Value.Default + Integer getAge() { + return 42; + } +} diff --git a/immutables/src/main/java/com/baeldung/immutable/parameter/Person.java b/immutables/src/main/java/com/baeldung/immutable/parameter/Person.java new file mode 100644 index 0000000000..4e8218f99c --- /dev/null +++ b/immutables/src/main/java/com/baeldung/immutable/parameter/Person.java @@ -0,0 +1,14 @@ +package com.baeldung.immutable.parameter; + + +import org.immutables.value.Value; + +@Value.Immutable +public abstract class Person { + + @Value.Parameter + abstract String getName(); + + @Value.Parameter + abstract Integer getAge(); +} \ No newline at end of file diff --git a/immutables/src/main/java/com/baeldung/immutable/prehash/Person.java b/immutables/src/main/java/com/baeldung/immutable/prehash/Person.java new file mode 100644 index 0000000000..5e5dd4d9e9 --- /dev/null +++ b/immutables/src/main/java/com/baeldung/immutable/prehash/Person.java @@ -0,0 +1,9 @@ +package com.baeldung.immutable.prehash; + +import org.immutables.value.Value; + +@Value.Immutable(prehash = true) +public abstract class Person { + abstract String getName(); + abstract Integer getAge(); +} diff --git a/immutables/src/test/java/com/baeldung/immutable/ImmutablePersonTest.java b/immutables/src/test/java/com/baeldung/immutable/ImmutablePersonTest.java new file mode 100644 index 0000000000..bf075569db --- /dev/null +++ b/immutables/src/test/java/com/baeldung/immutable/ImmutablePersonTest.java @@ -0,0 +1,27 @@ +package com.baeldung.immutable; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mutabilitydetector.unittesting.MutabilityAssert.assertImmutable; + +public class ImmutablePersonTest { + + @Test + public void whenModifying_shouldCreateNewInstance() throws Exception { + final ImmutablePerson john = ImmutablePerson.builder() + .age(42) + .name("John") + .build(); + + final ImmutablePerson john43 = john.withAge(43); + + assertThat(john) + .isNotSameAs(john43); + + assertThat(john.getAge()) + .isEqualTo(42); + + assertImmutable(ImmutablePerson.class); + } +} \ No newline at end of file diff --git a/immutables/src/test/java/com/baeldung/immutable/auxiliary/ImmutablePersonAuxiliaryTest.java b/immutables/src/test/java/com/baeldung/immutable/auxiliary/ImmutablePersonAuxiliaryTest.java new file mode 100644 index 0000000000..83f9e51ed5 --- /dev/null +++ b/immutables/src/test/java/com/baeldung/immutable/auxiliary/ImmutablePersonAuxiliaryTest.java @@ -0,0 +1,33 @@ +package com.baeldung.immutable.auxiliary; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ImmutablePersonAuxiliaryTest { + + @Test + public void whenComparing_shouldIgnore() throws Exception { + final ImmutablePerson john1 = ImmutablePerson.builder() + .name("John") + .age(42) + .auxiliaryField("Value1") + .build(); + + final ImmutablePerson john2 = ImmutablePerson.builder() + .name("John") + .age(42) + .auxiliaryField("Value2") + .build(); + + + assertThat(john1.equals(john2)) + .isTrue(); + + assertThat(john1.toString()) + .isEqualTo(john2.toString()); + + assertThat(john1.hashCode()) + .isEqualTo(john2.hashCode()); + } +} \ No newline at end of file diff --git a/immutables/src/test/java/com/baeldung/immutable/default_/ImmutablePersonDefaultTest.java b/immutables/src/test/java/com/baeldung/immutable/default_/ImmutablePersonDefaultTest.java new file mode 100644 index 0000000000..5cf4ac0cf7 --- /dev/null +++ b/immutables/src/test/java/com/baeldung/immutable/default_/ImmutablePersonDefaultTest.java @@ -0,0 +1,17 @@ +package com.baeldung.immutable.default_; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ImmutablePersonDefaultTest { + + @Test + public void whenInstantiating_shouldUseDefaultValue() throws Exception { + + final ImmutablePerson john = ImmutablePerson.builder().name("John").build(); + + assertThat(john.getAge()).isEqualTo(42); + + } +} \ No newline at end of file diff --git a/jackson/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch b/jackson/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch deleted file mode 100644 index 627021fb96..0000000000 --- a/jackson/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/jackson/.settings/.jsdtscope b/jackson/.settings/.jsdtscope deleted file mode 100644 index 7b3f0c8b9f..0000000000 --- a/jackson/.settings/.jsdtscope +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/jackson/.settings/org.eclipse.jdt.core.prefs b/jackson/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index b126d6476b..0000000000 --- a/jackson/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,95 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=error -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=error -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/jackson/.settings/org.eclipse.jdt.ui.prefs b/jackson/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100644 index 471e9b0d81..0000000000 --- a/jackson/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,55 +0,0 @@ -#Sat Jan 21 23:04:06 EET 2012 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=true -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=true -sp_cleanup.correct_indentation=true -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=true -sp_cleanup.make_local_variable_final=true -sp_cleanup.make_parameters_final=true -sp_cleanup.make_private_fields_final=false -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=true -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=false -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=true -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=true -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=true -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/jackson/.settings/org.eclipse.m2e.core.prefs b/jackson/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f1cb..0000000000 --- a/jackson/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/jackson/.settings/org.eclipse.m2e.wtp.prefs b/jackson/.settings/org.eclipse.m2e.wtp.prefs deleted file mode 100644 index ef86089622..0000000000 --- a/jackson/.settings/org.eclipse.m2e.wtp.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.m2e.wtp.enabledProjectSpecificPrefs=false diff --git a/jackson/.settings/org.eclipse.wst.common.component b/jackson/.settings/org.eclipse.wst.common.component deleted file mode 100644 index e98377cb0f..0000000000 --- a/jackson/.settings/org.eclipse.wst.common.component +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/jackson/.settings/org.eclipse.wst.common.project.facet.core.xml b/jackson/.settings/org.eclipse.wst.common.project.facet.core.xml deleted file mode 100644 index f4ef8aa0a5..0000000000 --- a/jackson/.settings/org.eclipse.wst.common.project.facet.core.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/jackson/.settings/org.eclipse.wst.jsdt.ui.superType.container b/jackson/.settings/org.eclipse.wst.jsdt.ui.superType.container deleted file mode 100644 index 3bd5d0a480..0000000000 --- a/jackson/.settings/org.eclipse.wst.jsdt.ui.superType.container +++ /dev/null @@ -1 +0,0 @@ -org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/jackson/.settings/org.eclipse.wst.jsdt.ui.superType.name b/jackson/.settings/org.eclipse.wst.jsdt.ui.superType.name deleted file mode 100644 index 05bd71b6ec..0000000000 --- a/jackson/.settings/org.eclipse.wst.jsdt.ui.superType.name +++ /dev/null @@ -1 +0,0 @@ -Window \ No newline at end of file diff --git a/jackson/.settings/org.eclipse.wst.validation.prefs b/jackson/.settings/org.eclipse.wst.validation.prefs deleted file mode 100644 index cacf5451ae..0000000000 --- a/jackson/.settings/org.eclipse.wst.validation.prefs +++ /dev/null @@ -1,14 +0,0 @@ -DELEGATES_PREFERENCE=delegateValidatorList -USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator; -USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator; -USER_PREFERENCE=overrideGlobalPreferencestruedisableAllValidationfalseversion1.2.303.v201202090300 -eclipse.preferences.version=1 -override=true -suspend=false -vals/org.eclipse.jst.jsf.ui.JSFAppConfigValidator/global=FF01 -vals/org.eclipse.jst.jsp.core.JSPBatchValidator/global=FF01 -vals/org.eclipse.jst.jsp.core.JSPContentValidator/global=FF01 -vals/org.eclipse.jst.jsp.core.TLDValidator/global=FF01 -vals/org.eclipse.wst.dtd.core.dtdDTDValidator/global=FF01 -vals/org.eclipse.wst.jsdt.web.core.JsBatchValidator/global=TF02 -vf.version=3 diff --git a/jackson/.settings/org.eclipse.wst.ws.service.policy.prefs b/jackson/.settings/org.eclipse.wst.ws.service.policy.prefs deleted file mode 100644 index 9cfcabe16f..0000000000 --- a/jackson/.settings/org.eclipse.wst.ws.service.policy.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.wst.ws.service.policy.projectEnabled=false diff --git a/jackson/README.md b/jackson/README.md index 68765de686..f48a7dc8ab 100644 --- a/jackson/README.md +++ b/jackson/README.md @@ -19,3 +19,8 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Jackson – Decide What Fields Get Serialized/Deserializaed](http://www.baeldung.com/jackson-field-serializable-deserializable-or-not) - [A Guide to Jackson Annotations](http://www.baeldung.com/jackson-annotations) - [Working with Tree Model Nodes in Jackson](http://www.baeldung.com/jackson-json-node-tree-model) +- [Jackson vs Gson](http://www.baeldung.com/jackson-vs-gson) +- [Intro to the Jackson ObjectMapper](http://www.baeldung.com/jackson-object-mapper-tutorial) +- [XML Serialization and Deserialization with Jackson](http://www.baeldung.com/jackson-xml-serialization-and-deserialization) +- [More Jackson Annotations](http://www.baeldung.com/jackson-advanced-annotations) +- [Inheritance with Jackson](http://www.baeldung.com/jackson-inheritance) diff --git a/jackson/pom.xml b/jackson/pom.xml index 17b0ac507e..e795ad11a2 100644 --- a/jackson/pom.xml +++ b/jackson/pom.xml @@ -174,7 +174,7 @@ 5.1.38 - 2.7.2 + 2.7.8 1.7.13 diff --git a/jackson/src/main/java/org/baeldung/jackson/entities/ActorJackson.java b/jackson/src/main/java/org/baeldung/jackson/entities/ActorJackson.java new file mode 100644 index 0000000000..375b2204ff --- /dev/null +++ b/jackson/src/main/java/org/baeldung/jackson/entities/ActorJackson.java @@ -0,0 +1,60 @@ +package org.baeldung.jackson.entities; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +public class ActorJackson { + + private String imdbId; + private Date dateOfBirth; + private List filmography; + + public ActorJackson() { + super(); + } + + public ActorJackson(String imdbId, Date dateOfBirth, List filmography) { + super(); + this.imdbId = imdbId; + this.dateOfBirth = dateOfBirth; + this.filmography = filmography; + } + + @Override + public String toString() { + return "ActorJackson [imdbId=" + imdbId + ", dateOfBirth=" + formatDateOfBirth() + ", filmography=" + filmography + "]"; + } + + public String getImdbId() { + return imdbId; + } + + public void setImdbId(String imdbId) { + this.imdbId = imdbId; + } + + public Date getDateOfBirth() { + return dateOfBirth; + } + + public void setDateOfBirth(Date dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } + + public List getFilmography() { + return filmography; + } + + public void setFilmography(List filmography) { + this.filmography = filmography; + } + + private String formatDateOfBirth() { + final DateFormat formatter = new SimpleDateFormat("EEE MMM dd hh:mm:ss zzz yyyy"); + formatter.setTimeZone(TimeZone.getTimeZone("GMT")); + return formatter.format(dateOfBirth); + } +} diff --git a/jackson/src/main/java/org/baeldung/jackson/entities/Movie.java b/jackson/src/main/java/org/baeldung/jackson/entities/Movie.java new file mode 100644 index 0000000000..68b7464563 --- /dev/null +++ b/jackson/src/main/java/org/baeldung/jackson/entities/Movie.java @@ -0,0 +1,50 @@ +package org.baeldung.jackson.entities; + +import java.util.List; + +public class Movie { + + private String imdbId; + private String director; + private List actors; + + public Movie(String imdbId, String director, List actors) { + super(); + this.imdbId = imdbId; + this.director = director; + this.actors = actors; + } + + public Movie() { + super(); + } + + @Override + public String toString() { + return "Movie [imdbId=" + imdbId + ", director=" + director + ", actors=" + actors + "]"; + } + + public String getImdbId() { + return imdbId; + } + + public void setImdbId(String imdbId) { + this.imdbId = imdbId; + } + + public String getDirector() { + return director; + } + + public void setDirector(String director) { + this.director = director; + } + + public List getActors() { + return actors; + } + + public void setActors(List actors) { + this.actors = actors; + } +} \ No newline at end of file diff --git a/jackson/src/main/java/org/baeldung/jackson/entities/MovieWithNullValue.java b/jackson/src/main/java/org/baeldung/jackson/entities/MovieWithNullValue.java new file mode 100644 index 0000000000..23f5de2858 --- /dev/null +++ b/jackson/src/main/java/org/baeldung/jackson/entities/MovieWithNullValue.java @@ -0,0 +1,46 @@ +package org.baeldung.jackson.entities; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +import java.util.List; + +public class MovieWithNullValue { + + private String imdbId; + + @JsonIgnore + private String director; + + private List actors; + + public MovieWithNullValue(String imdbID, String director, List actors) { + super(); + this.imdbId = imdbID; + this.director = director; + this.actors = actors; + } + + public String getImdbID() { + return imdbId; + } + + public void setImdbID(String imdbID) { + this.imdbId = imdbID; + } + + public String getDirector() { + return director; + } + + public void setDirector(String director) { + this.director = director; + } + + public List getActors() { + return actors; + } + + public void setActors(List actors) { + this.actors = actors; + } +} \ No newline at end of file diff --git a/jackson/src/main/java/org/baeldung/jackson/serialization/ActorJacksonSerializer.java b/jackson/src/main/java/org/baeldung/jackson/serialization/ActorJacksonSerializer.java new file mode 100644 index 0000000000..c33cf59482 --- /dev/null +++ b/jackson/src/main/java/org/baeldung/jackson/serialization/ActorJacksonSerializer.java @@ -0,0 +1,31 @@ +package org.baeldung.jackson.serialization; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.stream.Collectors; + +import org.baeldung.jackson.entities.ActorJackson; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class ActorJacksonSerializer extends StdSerializer { + + private SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); + + public ActorJacksonSerializer(Class t) { + super(t); + } + + @Override + public void serialize(ActorJackson actor, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + + jsonGenerator.writeStartObject(); + jsonGenerator.writeStringField("imdbId", actor.getImdbId()); + jsonGenerator.writeObjectField("dateOfBirth", actor.getDateOfBirth() != null ? sdf.format(actor.getDateOfBirth()) : null); + jsonGenerator.writeNumberField("N° Film: ", actor.getFilmography() != null ? actor.getFilmography().size() : null); + jsonGenerator.writeStringField("filmography", actor.getFilmography().stream().collect(Collectors.joining("-"))); + jsonGenerator.writeEndObject(); + } +} \ No newline at end of file diff --git a/jackson/src/test/java/org/baeldung/jackson/deserialization/JacksonDeserializeTest.java b/jackson/src/test/java/org/baeldung/jackson/deserialization/JacksonDeserializeTest.java new file mode 100644 index 0000000000..503b6eb99b --- /dev/null +++ b/jackson/src/test/java/org/baeldung/jackson/deserialization/JacksonDeserializeTest.java @@ -0,0 +1,41 @@ +package org.baeldung.jackson.deserialization; + +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +import org.baeldung.jackson.entities.Movie; +import org.junit.Assert; +import org.junit.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JacksonDeserializeTest { + + @Test + public void whenSimpleDeserialize_thenCorrect() throws IOException { + + final String jsonInput = "{\"imdbId\":\"tt0472043\",\"actors\":[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"1982-09-21T12:00:00+01:00\",\"filmography\":[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}"; + final ObjectMapper mapper = new ObjectMapper(); + final Movie movie = mapper.readValue(jsonInput, Movie.class); + + final String expectedOutput = "Movie [imdbId=tt0472043, director=null, actors=[ActorJackson [imdbId=nm2199632, dateOfBirth=Tue Sep 21 11:00:00 GMT 1982, filmography=[Apocalypto, Beatdown, Wind Walkers]]]]"; + Assert.assertEquals(movie.toString(), expectedOutput); + } + + @Test + public void whenCustomDeserialize_thenCorrect() throws IOException { + + final String jsonInput = "{\"imdbId\":\"tt0472043\",\"director\":\"Mel Gibson\",\"actors\":[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"1982-09-21T12:00:00+01:00\",\"filmography\":[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}"; + + final ObjectMapper mapper = new ObjectMapper(); + final DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); + mapper.setDateFormat(df); + + final Movie movie = mapper.readValue(jsonInput, Movie.class); + + final String expectedOutput = "Movie [imdbId=tt0472043, director=Mel Gibson, actors=[ActorJackson [imdbId=nm2199632, dateOfBirth=Tue Sep 21 11:00:00 GMT 1982, filmography=[Apocalypto, Beatdown, Wind Walkers]]]]"; + Assert.assertEquals(movie.toString(), expectedOutput); + } + +} diff --git a/jackson/src/test/java/org/baeldung/jackson/serialization/JacksonSerializeTest.java b/jackson/src/test/java/org/baeldung/jackson/serialization/JacksonSerializeTest.java new file mode 100644 index 0000000000..6d9e378025 --- /dev/null +++ b/jackson/src/test/java/org/baeldung/jackson/serialization/JacksonSerializeTest.java @@ -0,0 +1,58 @@ +package org.baeldung.jackson.serialization; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.TimeZone; + +import org.baeldung.jackson.entities.ActorJackson; +import org.baeldung.jackson.entities.Movie; +import org.baeldung.jackson.entities.MovieWithNullValue; +import org.junit.Assert; +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.module.SimpleModule; + +public class JacksonSerializeTest { + + @Test + public void whenSimpleSerialize_thenCorrect() throws JsonProcessingException, ParseException { + + final SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + + final ActorJackson rudyYoungblood = new ActorJackson("nm2199632", sdf.parse("21-09-1982"), Arrays.asList("Apocalypto", "Beatdown", "Wind Walkers")); + final Movie movie = new Movie("tt0472043", "Mel Gibson", Arrays.asList(rudyYoungblood)); + + final ObjectMapper mapper = new ObjectMapper(); + final String jsonResult = mapper.writeValueAsString(movie); + + final String expectedOutput = "{\"imdbId\":\"tt0472043\",\"director\":\"Mel Gibson\",\"actors\":[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":401414400000,\"filmography\":[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}"; + Assert.assertEquals(jsonResult, expectedOutput); + } + + @Test + public void whenCustomSerialize_thenCorrect() throws ParseException, IOException { + + final SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); + + final ActorJackson rudyYoungblood = new ActorJackson("nm2199632", sdf.parse("21-09-1982"), Arrays.asList("Apocalypto", "Beatdown", "Wind Walkers")); + final MovieWithNullValue movieWithNullValue = new MovieWithNullValue(null, "Mel Gibson", Arrays.asList(rudyYoungblood)); + + final SimpleModule module = new SimpleModule(); + module.addSerializer(new ActorJacksonSerializer(ActorJackson.class)); + final ObjectMapper mapper = new ObjectMapper(); + + final String jsonResult = mapper.registerModule(module).writer(new DefaultPrettyPrinter()).writeValueAsString(movieWithNullValue); + + final Object json = mapper.readValue("{\"actors\":[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"21-09-1982\",\"N° Film: \":3,\"filmography\":\"Apocalypto-Beatdown-Wind Walkers\"}],\"imdbID\":null}", Object.class); + final String expectedOutput = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT).writeValueAsString(json); + + Assert.assertEquals(jsonResult, expectedOutput); + } +} diff --git a/java-cassandra/pom.xml b/java-cassandra/pom.xml new file mode 100644 index 0000000000..92d3a8ede6 --- /dev/null +++ b/java-cassandra/pom.xml @@ -0,0 +1,152 @@ + + 4.0.0 + com.baeldung + cassandra-java-client + 1.0.0-SNAPSHOT + + cassandra-java-client + + + + + com.datastax.cassandra + cassandra-driver-core + ${cassandra-driver-core.version} + true + + + + + org.cassandraunit + cassandra-unit + 3.0.0.1 + + + + + com.google.guava + guava + ${guava.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 + + + + + java-cassandra + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + + UTF-8 + + 19.0 + + + 1.7.21 + 1.1.7 + + + 1.3 + 4.12 + 1.10.19 + 6.8 + 3.5.1 + + + 3.5.1 + 2.19.1 + + + 3.1.0 + + + diff --git a/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraClient.java b/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraClient.java new file mode 100644 index 0000000000..c67a2c2ddb --- /dev/null +++ b/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraClient.java @@ -0,0 +1,44 @@ +package com.baeldung.cassandra.java.client; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.baeldung.cassandra.java.client.domain.Book; +import com.baeldung.cassandra.java.client.repository.BookRepository; +import com.baeldung.cassandra.java.client.repository.KeyspaceRepository; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.utils.UUIDs; + +public class CassandraClient { + private static final Logger LOG = LoggerFactory.getLogger(CassandraClient.class); + + public static void main(String args[]) { + CassandraConnector connector = new CassandraConnector(); + connector.connect("127.0.0.1", null); + Session session = connector.getSession(); + + KeyspaceRepository sr = new KeyspaceRepository(session); + sr.createKeyspace("library", "SimpleStrategy", 1); + sr.useKeyspace("library"); + + BookRepository br = new BookRepository(session); + br.createTable(); + br.alterTablebooks("publisher", "text"); + + br.createTableBooksByTitle(); + + Book book = new Book(UUIDs.timeBased(), "Effective Java", "Joshua Bloch", "Programming"); + br.insertBookBatch(book); + + br.selectAll().forEach(o -> LOG.info("Title in books: " + o.getTitle())); + br.selectAllBookByTitle().forEach(o -> LOG.info("Title in booksByTitle: " + o.getTitle())); + + br.deletebookByTitle("Effective Java"); + br.deleteTable("books"); + br.deleteTable("booksByTitle"); + + sr.deleteKeyspace("library"); + + connector.close(); + } +} diff --git a/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraConnector.java b/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraConnector.java new file mode 100644 index 0000000000..e035335ca0 --- /dev/null +++ b/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraConnector.java @@ -0,0 +1,51 @@ +package com.baeldung.cassandra.java.client; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.Cluster.Builder; +import com.datastax.driver.core.Host; +import com.datastax.driver.core.Metadata; +import com.datastax.driver.core.Session; + +/** + * + * This is an implementation of a simple Java client. + * + */ +public class CassandraConnector { + private static final Logger LOG = LoggerFactory.getLogger(CassandraConnector.class); + + private Cluster cluster; + + private Session session; + + public void connect(final String node, final Integer port) { + + Builder b = Cluster.builder().addContactPoint(node); + + if (port != null) { + b.withPort(port); + } + cluster = b.build(); + + Metadata metadata = cluster.getMetadata(); + LOG.info("Cluster name: " + metadata.getClusterName()); + + for (Host host : metadata.getAllHosts()) { + LOG.info("Datacenter: " + host.getDatacenter() + " Host: " + host.getAddress() + " Rack: " + host.getRack()); + } + + session = cluster.connect(); + } + + public Session getSession() { + return this.session; + } + + public void close() { + session.close(); + cluster.close(); + } +} diff --git a/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/domain/Book.java b/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/domain/Book.java new file mode 100644 index 0000000000..e6c7753eb3 --- /dev/null +++ b/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/domain/Book.java @@ -0,0 +1,66 @@ +package com.baeldung.cassandra.java.client.domain; + +import java.util.UUID; + +public class Book { + + private UUID id; + + private String title; + + private String author; + + private String subject; + + private String publisher; + + Book() { + } + + public Book(UUID id, String title, String author, String subject) { + this.id = id; + this.title = title; + this.author = author; + this.subject = subject; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getPublisher() { + return publisher; + } + + public void setPublisher(String publisher) { + this.publisher = publisher; + } +} diff --git a/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/BookRepository.java b/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/BookRepository.java new file mode 100644 index 0000000000..31e2969e01 --- /dev/null +++ b/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/BookRepository.java @@ -0,0 +1,177 @@ +package com.baeldung.cassandra.java.client.repository; + +import java.util.ArrayList; +import java.util.List; + +import com.baeldung.cassandra.java.client.domain.Book; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; + +public class BookRepository { + + private static final String TABLE_NAME = "books"; + + private static final String TABLE_NAME_BY_TITLE = TABLE_NAME + "ByTitle"; + + private Session session; + + public BookRepository(Session session) { + this.session = session; + } + + /** + * Creates the books table. + */ + public void createTable() { + StringBuilder sb = new StringBuilder("CREATE TABLE IF NOT EXISTS ").append(TABLE_NAME).append("(").append("id uuid PRIMARY KEY, ").append("title text,").append("author text,").append("subject text);"); + + final String query = sb.toString(); + session.execute(query); + } + + /** + * Creates the books table. + */ + public void createTableBooksByTitle() { + StringBuilder sb = new StringBuilder("CREATE TABLE IF NOT EXISTS ").append(TABLE_NAME_BY_TITLE).append("(").append("id uuid, ").append("title text,").append("PRIMARY KEY (title, id));"); + + final String query = sb.toString(); + session.execute(query); + } + + /** + * Alters the table books and adds an extra column. + */ + public void alterTablebooks(String columnName, String columnType) { + StringBuilder sb = new StringBuilder("ALTER TABLE ").append(TABLE_NAME).append(" ADD ").append(columnName).append(" ").append(columnType).append(";"); + + final String query = sb.toString(); + session.execute(query); + } + + /** + * Insert a row in the table books. + * + * @param book + */ + public void insertbook(Book book) { + StringBuilder sb = new StringBuilder("INSERT INTO ").append(TABLE_NAME).append("(id, title, author, subject) ").append("VALUES (").append(book.getId()).append(", '").append(book.getTitle()).append("', '").append(book.getAuthor()).append("', '") + .append(book.getSubject()).append("');"); + + final String query = sb.toString(); + session.execute(query); + } + + /** + * Insert a row in the table booksByTitle. + * @param book + */ + public void insertbookByTitle(Book book) { + StringBuilder sb = new StringBuilder("INSERT INTO ").append(TABLE_NAME_BY_TITLE).append("(id, title) ").append("VALUES (").append(book.getId()).append(", '").append(book.getTitle()).append("');"); + + final String query = sb.toString(); + session.execute(query); + } + + /** + * Insert a book into two identical tables using a batch query. + * + * @param book + */ + public void insertBookBatch(Book book) { + StringBuilder sb = new StringBuilder("BEGIN BATCH ") + .append("INSERT INTO ").append(TABLE_NAME).append("(id, title, author, subject) ") + .append("VALUES (").append(book.getId()).append(", '").append(book.getTitle()).append("', '").append(book.getAuthor()).append("', '") + .append(book.getSubject()).append("');") + .append("INSERT INTO ").append(TABLE_NAME_BY_TITLE).append("(id, title) ") + .append("VALUES (").append(book.getId()).append(", '").append(book.getTitle()).append("');") + .append("APPLY BATCH;"); + + final String query = sb.toString(); + session.execute(query); + } + + /** + * Select book by id. + * + * @return + */ + public Book selectByTitle(String title) { + StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME_BY_TITLE).append(" WHERE title = '").append(title).append("';"); + + final String query = sb.toString(); + + ResultSet rs = session.execute(query); + + List books = new ArrayList(); + + for (Row r : rs) { + Book s = new Book(r.getUUID("id"), r.getString("title"), null, null); + books.add(s); + } + + return books.get(0); + } + + /** + * Select all books from books + * + * @return + */ + public List selectAll() { + StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME); + + final String query = sb.toString(); + ResultSet rs = session.execute(query); + + List books = new ArrayList(); + + for (Row r : rs) { + Book book = new Book(r.getUUID("id"), r.getString("title"), r.getString("author"), r.getString("subject")); + books.add(book); + } + return books; + } + + /** + * Select all books from booksByTitle + * @return + */ + public List selectAllBookByTitle() { + StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME_BY_TITLE); + + final String query = sb.toString(); + ResultSet rs = session.execute(query); + + List books = new ArrayList(); + + for (Row r : rs) { + Book book = new Book(r.getUUID("id"), r.getString("title"), null, null); + books.add(book); + } + return books; + } + + /** + * Delete a book by title. + */ + public void deletebookByTitle(String title) { + StringBuilder sb = new StringBuilder("DELETE FROM ").append(TABLE_NAME_BY_TITLE).append(" WHERE title = '").append(title).append("';"); + + final String query = sb.toString(); + session.execute(query); + } + + /** + * Delete table. + * + * @param tableName the name of the table to delete. + */ + public void deleteTable(String tableName) { + StringBuilder sb = new StringBuilder("DROP TABLE IF EXISTS ").append(tableName); + + final String query = sb.toString(); + session.execute(query); + } +} diff --git a/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepository.java b/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepository.java new file mode 100644 index 0000000000..f15558f040 --- /dev/null +++ b/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepository.java @@ -0,0 +1,49 @@ +package com.baeldung.cassandra.java.client.repository; + +import com.datastax.driver.core.Session; + +/** + * Repository to handle the Cassandra schema. + * + */ +public class KeyspaceRepository { + private Session session; + + public KeyspaceRepository(Session session) { + this.session = session; + } + + /** + * Method used to create any keyspace - schema. + * + * @param schemaName the name of the schema. + * @param replicatioonStrategy the replication strategy. + * @param numberOfReplicas the number of replicas. + * + */ + public void createKeyspace(String keyspaceName, String replicatioonStrategy, int numberOfReplicas) { + StringBuilder sb = new StringBuilder("CREATE KEYSPACE IF NOT EXISTS ").append(keyspaceName).append(" WITH replication = {").append("'class':'").append(replicatioonStrategy).append("','replication_factor':").append(numberOfReplicas).append("};"); + + final String query = sb.toString(); + + session.execute(query); + } + + public void useKeyspace(String keyspace) { + session.execute("USE " + keyspace); + } + + /** + * Method used to delete the specified schema. + * It results in the immediate, irreversable removal of the keyspace, including all tables and data contained in the keyspace. + * + * @param schemaName the name of the keyspace to delete. + */ + public void deleteKeyspace(String keyspaceName) { + StringBuilder sb = new StringBuilder("DROP KEYSPACE ").append(keyspaceName); + + final String query = sb.toString(); + + session.execute(query); + } +} diff --git a/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/BookRepositoryIntegrationTest.java b/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/BookRepositoryIntegrationTest.java new file mode 100644 index 0000000000..62eae94c7c --- /dev/null +++ b/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/BookRepositoryIntegrationTest.java @@ -0,0 +1,174 @@ +package com.baeldung.cassandra.java.client.repository; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.thrift.transport.TTransportException; +import org.cassandraunit.utils.EmbeddedCassandraServerHelper; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.baeldung.cassandra.java.client.CassandraConnector; +import com.baeldung.cassandra.java.client.domain.Book; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.exceptions.InvalidQueryException; +import com.datastax.driver.core.utils.UUIDs; + +public class BookRepositoryIntegrationTest { + + private KeyspaceRepository schemaRepository; + + private BookRepository bookRepository; + + private Session session; + + final String KEYSPACE_NAME = "testLibrary"; + final String BOOKS = "books"; + final String BOOKS_BY_TITLE = "booksByTitle"; + + @BeforeClass + public static void init() throws ConfigurationException, TTransportException, IOException, InterruptedException { + // Start an embedded Cassandra Server + EmbeddedCassandraServerHelper.startEmbeddedCassandra(20000L); + } + + @Before + public void connect() { + CassandraConnector client = new CassandraConnector(); + client.connect("127.0.0.1", 9142); + this.session = client.getSession(); + schemaRepository = new KeyspaceRepository(session); + schemaRepository.createKeyspace(KEYSPACE_NAME, "SimpleStrategy", 1); + schemaRepository.useKeyspace(KEYSPACE_NAME); + bookRepository = new BookRepository(session); + } + + @Test + public void whenCreatingATable_thenCreatedCorrectly() { + bookRepository.deleteTable(BOOKS); + bookRepository.createTable(); + + ResultSet result = session.execute("SELECT * FROM " + KEYSPACE_NAME + "." + BOOKS + ";"); + + // Collect all the column names in one list. + List columnNames = result.getColumnDefinitions().asList().stream().map(cl -> cl.getName()).collect(Collectors.toList()); + assertEquals(columnNames.size(), 4); + assertTrue(columnNames.contains("id")); + assertTrue(columnNames.contains("title")); + assertTrue(columnNames.contains("author")); + assertTrue(columnNames.contains("subject")); + } + + @Test + public void whenAlteringTable_thenAddedColumnExists() { + bookRepository.deleteTable(BOOKS); + bookRepository.createTable(); + + bookRepository.alterTablebooks("publisher", "text"); + + ResultSet result = session.execute("SELECT * FROM " + KEYSPACE_NAME + "." + BOOKS + ";"); + + boolean columnExists = result.getColumnDefinitions().asList().stream().anyMatch(cl -> cl.getName().equals("publisher")); + assertTrue(columnExists); + } + + @Test + public void whenAddingANewBook_thenBookExists() { + bookRepository.deleteTable(BOOKS_BY_TITLE); + bookRepository.createTableBooksByTitle(); + + String title = "Effective Java"; + String author = "Joshua Bloch"; + Book book = new Book(UUIDs.timeBased(), title, author, "Programming"); + bookRepository.insertbookByTitle(book); + + Book savedBook = bookRepository.selectByTitle(title); + assertEquals(book.getTitle(), savedBook.getTitle()); + } + + @Test + public void whenAddingANewBookBatch_ThenBookAddedInAllTables() { + // Create table books + bookRepository.deleteTable(BOOKS); + bookRepository.createTable(); + + // Create table booksByTitle + bookRepository.deleteTable(BOOKS_BY_TITLE); + bookRepository.createTableBooksByTitle(); + + String title = "Effective Java"; + String author = "Joshua Bloch"; + Book book = new Book(UUIDs.timeBased(), title, author, "Programming"); + bookRepository.insertBookBatch(book); + + List books = bookRepository.selectAll(); + + assertEquals(1, books.size()); + assertTrue(books.stream().anyMatch(b -> b.getTitle().equals("Effective Java"))); + + List booksByTitle = bookRepository.selectAllBookByTitle(); + + assertEquals(1, booksByTitle.size()); + assertTrue(booksByTitle.stream().anyMatch(b -> b.getTitle().equals("Effective Java"))); + } + + @Test + public void whenSelectingAll_thenReturnAllRecords() { + bookRepository.deleteTable(BOOKS); + bookRepository.createTable(); + + Book book = new Book(UUIDs.timeBased(), "Effective Java", "Joshua Bloch", "Programming"); + bookRepository.insertbook(book); + + book = new Book(UUIDs.timeBased(), "Clean Code", "Robert C. Martin", "Programming"); + bookRepository.insertbook(book); + + List books = bookRepository.selectAll(); + + assertEquals(2, books.size()); + assertTrue(books.stream().anyMatch(b -> b.getTitle().equals("Effective Java"))); + assertTrue(books.stream().anyMatch(b -> b.getTitle().equals("Clean Code"))); + } + + @Test + public void whenDeletingABookByTitle_thenBookIsDeleted() { + bookRepository.deleteTable(BOOKS_BY_TITLE); + bookRepository.createTableBooksByTitle(); + + Book book = new Book(UUIDs.timeBased(), "Effective Java", "Joshua Bloch", "Programming"); + bookRepository.insertbookByTitle(book); + + book = new Book(UUIDs.timeBased(), "Clean Code", "Robert C. Martin", "Programming"); + bookRepository.insertbookByTitle(book); + + bookRepository.deletebookByTitle("Clean Code"); + + List books = bookRepository.selectAllBookByTitle(); + assertEquals(1, books.size()); + assertTrue(books.stream().anyMatch(b -> b.getTitle().equals("Effective Java"))); + assertFalse(books.stream().anyMatch(b -> b.getTitle().equals("Clean Code"))); + + } + + @Test(expected = InvalidQueryException.class) + public void whenDeletingATable_thenUnconfiguredTable() { + bookRepository.createTable(); + bookRepository.deleteTable(BOOKS); + + session.execute("SELECT * FROM " + KEYSPACE_NAME + "." + BOOKS + ";"); + } + + @AfterClass + public static void cleanup() { + EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); + } +} diff --git a/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepositoryIntegrationTest.java b/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepositoryIntegrationTest.java new file mode 100644 index 0000000000..9df46b3176 --- /dev/null +++ b/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepositoryIntegrationTest.java @@ -0,0 +1,77 @@ +package com.baeldung.cassandra.java.client.repository; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.thrift.transport.TTransportException; +import org.cassandraunit.utils.EmbeddedCassandraServerHelper; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import com.baeldung.cassandra.java.client.CassandraConnector; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Session; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class KeyspaceRepositoryIntegrationTest { + + private KeyspaceRepository schemaRepository; + + private Session session; + + @BeforeClass + public static void init() throws ConfigurationException, TTransportException, IOException, InterruptedException { + // Start an embedded Cassandra Server + EmbeddedCassandraServerHelper.startEmbeddedCassandra(20000L); + } + + @Before + public void connect() { + CassandraConnector client = new CassandraConnector(); + client.connect("127.0.0.1", 9142); + this.session = client.getSession(); + schemaRepository = new KeyspaceRepository(session); + } + + @Test + public void whenCreatingAKeyspace_thenCreated() { + String keyspaceName = "testBaeldungKeyspace"; + schemaRepository.createKeyspace(keyspaceName, "SimpleStrategy", 1); + + // ResultSet result = session.execute("SELECT * FROM system_schema.keyspaces WHERE keyspace_name = 'testBaeldungKeyspace';"); + + ResultSet result = session.execute("SELECT * FROM system_schema.keyspaces;"); + + // Check if the Keyspace exists in the returned keyspaces. + List matchedKeyspaces = result.all().stream().filter(r -> r.getString(0).equals(keyspaceName.toLowerCase())).map(r -> r.getString(0)).collect(Collectors.toList()); + assertEquals(matchedKeyspaces.size(), 1); + assertTrue(matchedKeyspaces.get(0).equals(keyspaceName.toLowerCase())); + } + + @Test + public void whenDeletingAKeyspace_thenDoesNotExist() { + String keyspaceName = "testBaeldungKeyspace"; + + // schemaRepository.createKeyspace(keyspaceName, "SimpleStrategy", 1); + schemaRepository.deleteKeyspace(keyspaceName); + + ResultSet result = session.execute("SELECT * FROM system_schema.keyspaces;"); + boolean isKeyspaceCreated = result.all().stream().anyMatch(r -> r.getString(0).equals(keyspaceName.toLowerCase())); + assertFalse(isKeyspaceCreated); + } + + @AfterClass + public static void cleanup() { + EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); + } +} diff --git a/jee7/README.md b/jee7/README.md new file mode 100644 index 0000000000..44ca9c2f6e --- /dev/null +++ b/jee7/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Scheduling in Java EE](http://www.baeldung.com/scheduling-in-java-enterprise-edition) diff --git a/jee7schedule/pom.xml b/jee7/pom.xml similarity index 100% rename from jee7schedule/pom.xml rename to jee7/pom.xml diff --git a/jee7schedule/src/main/java/com/baeldung/timer/AutomaticTimerBean.java b/jee7/src/main/java/com/baeldung/timer/AutomaticTimerBean.java similarity index 100% rename from jee7schedule/src/main/java/com/baeldung/timer/AutomaticTimerBean.java rename to jee7/src/main/java/com/baeldung/timer/AutomaticTimerBean.java diff --git a/jee7schedule/src/main/java/com/baeldung/timer/FixedDelayTimerBean.java b/jee7/src/main/java/com/baeldung/timer/FixedDelayTimerBean.java similarity index 100% rename from jee7schedule/src/main/java/com/baeldung/timer/FixedDelayTimerBean.java rename to jee7/src/main/java/com/baeldung/timer/FixedDelayTimerBean.java diff --git a/jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBean.java b/jee7/src/main/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBean.java similarity index 100% rename from jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBean.java rename to jee7/src/main/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBean.java diff --git a/jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticTimerBean.java b/jee7/src/main/java/com/baeldung/timer/ProgrammaticTimerBean.java similarity index 100% rename from jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticTimerBean.java rename to jee7/src/main/java/com/baeldung/timer/ProgrammaticTimerBean.java diff --git a/jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticWithInitialFixedDelayTimerBean.java b/jee7/src/main/java/com/baeldung/timer/ProgrammaticWithInitialFixedDelayTimerBean.java similarity index 100% rename from jee7schedule/src/main/java/com/baeldung/timer/ProgrammaticWithInitialFixedDelayTimerBean.java rename to jee7/src/main/java/com/baeldung/timer/ProgrammaticWithInitialFixedDelayTimerBean.java diff --git a/jee7schedule/src/main/java/com/baeldung/timer/ScheduleTimerBean.java b/jee7/src/main/java/com/baeldung/timer/ScheduleTimerBean.java similarity index 100% rename from jee7schedule/src/main/java/com/baeldung/timer/ScheduleTimerBean.java rename to jee7/src/main/java/com/baeldung/timer/ScheduleTimerBean.java diff --git a/jee7schedule/src/main/java/com/baeldung/timer/TimerEvent.java b/jee7/src/main/java/com/baeldung/timer/TimerEvent.java similarity index 100% rename from jee7schedule/src/main/java/com/baeldung/timer/TimerEvent.java rename to jee7/src/main/java/com/baeldung/timer/TimerEvent.java diff --git a/jee7schedule/src/main/java/com/baeldung/timer/TimerEventListener.java b/jee7/src/main/java/com/baeldung/timer/TimerEventListener.java similarity index 100% rename from jee7schedule/src/main/java/com/baeldung/timer/TimerEventListener.java rename to jee7/src/main/java/com/baeldung/timer/TimerEventListener.java diff --git a/jee7schedule/src/main/java/com/baeldung/timer/WorkerBean.java b/jee7/src/main/java/com/baeldung/timer/WorkerBean.java similarity index 100% rename from jee7schedule/src/main/java/com/baeldung/timer/WorkerBean.java rename to jee7/src/main/java/com/baeldung/timer/WorkerBean.java diff --git a/xmlunit2-tutorial/README.md b/jee7/src/main/webapp/WEB-INF/beans.xml similarity index 100% rename from xmlunit2-tutorial/README.md rename to jee7/src/main/webapp/WEB-INF/beans.xml diff --git a/jee7schedule/src/test/java/com/baeldung/timer/AutomaticTimerBeanTest.java b/jee7/src/test/java/com/baeldung/timer/AutomaticTimerBeanTest.java similarity index 100% rename from jee7schedule/src/test/java/com/baeldung/timer/AutomaticTimerBeanTest.java rename to jee7/src/test/java/com/baeldung/timer/AutomaticTimerBeanTest.java diff --git a/jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanTest.java b/jee7/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanTest.java similarity index 100% rename from jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanTest.java rename to jee7/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanTest.java diff --git a/jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanTest.java b/jee7/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanTest.java similarity index 100% rename from jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanTest.java rename to jee7/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanTest.java diff --git a/jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanTest.java b/jee7/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanTest.java similarity index 100% rename from jee7schedule/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanTest.java rename to jee7/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanTest.java diff --git a/jee7schedule/src/test/java/com/baeldung/timer/ScheduleTimerBeanTest.java b/jee7/src/test/java/com/baeldung/timer/ScheduleTimerBeanTest.java similarity index 100% rename from jee7schedule/src/test/java/com/baeldung/timer/ScheduleTimerBeanTest.java rename to jee7/src/test/java/com/baeldung/timer/ScheduleTimerBeanTest.java diff --git a/jee7schedule/src/test/java/com/baeldung/timer/WithinWindowMatcher.java b/jee7/src/test/java/com/baeldung/timer/WithinWindowMatcher.java similarity index 100% rename from jee7schedule/src/test/java/com/baeldung/timer/WithinWindowMatcher.java rename to jee7/src/test/java/com/baeldung/timer/WithinWindowMatcher.java diff --git a/jjwt/pom.xml b/jjwt/pom.xml index 24f1c5c5ab..d2a3f1cdd8 100644 --- a/jjwt/pom.xml +++ b/jjwt/pom.xml @@ -58,8 +58,51 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*IntegrationTest.java + **/*LiveTest.java + + + - - - + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + diff --git a/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/DemoApplicationTests.java b/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/DemoApplicationIntegrationTest.java similarity index 91% rename from jjwt/src/test/java/io/jsonwebtoken/jjwtfun/DemoApplicationTests.java rename to jjwt/src/test/java/io/jsonwebtoken/jjwtfun/DemoApplicationIntegrationTest.java index 82138ea23e..df147232d9 100644 --- a/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/DemoApplicationTests.java +++ b/jjwt/src/test/java/io/jsonwebtoken/jjwtfun/DemoApplicationIntegrationTest.java @@ -9,7 +9,7 @@ import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = JJWTFunApplication.class) @WebAppConfiguration -public class DemoApplicationTests { +public class DemoApplicationIntegrationTest { @Test public void contextLoads() { diff --git a/jpa-storedprocedure/README.md b/jpa-storedprocedure/README.md new file mode 100644 index 0000000000..39d6784d8b --- /dev/null +++ b/jpa-storedprocedure/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures) diff --git a/jpa-storedprocedure/pom.xml b/jpa-storedprocedure/pom.xml index b2ebaa32e2..b5a2e8693c 100644 --- a/jpa-storedprocedure/pom.xml +++ b/jpa-storedprocedure/pom.xml @@ -11,6 +11,7 @@ 7.0 5.1.0.Final 5.1.38 + 2.19.1 @@ -33,6 +34,16 @@ + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + **/*IntegrationTest.java + + + diff --git a/jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureTest.java b/jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureIntegrationTest.java similarity index 98% rename from jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureTest.java rename to jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureIntegrationTest.java index 69351d9683..c93d59fe30 100644 --- a/jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureTest.java +++ b/jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureIntegrationTest.java @@ -15,7 +15,7 @@ import org.junit.Test; import com.baeldung.jpa.model.Car; -public class StoredProcedureTest { +public class StoredProcedureIntegrationTest { private static EntityManagerFactory factory = null; private static EntityManager entityManager = null; diff --git a/jsf/README.md b/jsf/README.md new file mode 100644 index 0000000000..ae92ffc42f --- /dev/null +++ b/jsf/README.md @@ -0,0 +1,4 @@ +### Relevant Articles: +- [Introduction to JSF Expression Language 3.0](http://www.baeldung.com/jsf-expression-language-el-3) +- [Introduction to JSF EL 2](http://www.baeldung.com/intro-to-jsf-expression-language) +- [JavaServer Faces (JSF) with Spring](http://www.baeldung.com/spring-jsf) diff --git a/jsf/pom.xml b/jsf/pom.xml index b80bcfb416..6a4b358252 100644 --- a/jsf/pom.xml +++ b/jsf/pom.xml @@ -27,7 +27,7 @@ javax.el - el-api + javax.el-api ${javax.el.version} @@ -126,8 +126,8 @@ 4.2.5.RELEASE - 2.1.7 - 2.2 + 2.2.13 + 3.0.0 1.7.13 diff --git a/jsf/src/main/java/com/baeldung/springintegration/controllers/ELSampleBean.java b/jsf/src/main/java/com/baeldung/springintegration/controllers/ELSampleBean.java index a13f0890b5..16d9f80d89 100644 --- a/jsf/src/main/java/com/baeldung/springintegration/controllers/ELSampleBean.java +++ b/jsf/src/main/java/com/baeldung/springintegration/controllers/ELSampleBean.java @@ -1,13 +1,17 @@ package com.baeldung.springintegration.controllers; -import java.util.Random; import javax.annotation.PostConstruct; +import javax.el.ELContextEvent; +import javax.el.ELContextListener; +import javax.el.LambdaExpression; import javax.faces.application.Application; import javax.faces.application.FacesMessage; +import javax.el.LambdaExpression; import javax.faces.bean.ManagedBean; import javax.faces.bean.ViewScoped; -import javax.faces.component.html.HtmlInputText; import javax.faces.context.FacesContext; +import java.util.Collection; +import java.util.Random; @ManagedBean(name = "ELBean") @ViewScoped @@ -16,22 +20,37 @@ public class ELSampleBean { private String firstName; private String lastName; private String pageDescription = "This page demos JSF EL Basics"; + public static final String constantField = "THIS_IS_NOT_CHANGING_ANYTIME_SOON"; private int pageCounter; private Random randomIntGen = new Random(); @PostConstruct public void init() { pageCounter = randomIntGen.nextInt(); + FacesContext.getCurrentInstance().getApplication().addELContextListener(new ELContextListener() { + @Override + public void contextCreated(ELContextEvent evt) { + evt.getELContext().getImportHandler().importClass("com.baeldung.springintegration.controllers.ELSampleBean"); + } + }); } public void save() { } + + public static String constantField() { + return constantField; + } public void saveFirstName(String firstName) { this.firstName = firstName; } + public Long multiplyValue(LambdaExpression expr) { + Long theResult = (Long) expr.invoke(FacesContext.getCurrentInstance().getELContext(), pageCounter); + return theResult; + } public void saveByELEvaluation() { firstName = (String) evaluateEL("#{firstName.value}", String.class); diff --git a/jsf/src/main/webapp/el3_intro.xhtml b/jsf/src/main/webapp/el3_intro.xhtml new file mode 100644 index 0000000000..3f1f407a08 --- /dev/null +++ b/jsf/src/main/webapp/el3_intro.xhtml @@ -0,0 +1,35 @@ + + + + + Baeldung | Expression Language 3.0 + + + + +
+ + +
+ + +
+ + +
+ + + +
+ + + + + + + +
+ + diff --git a/json/README.md b/json/README.md index c47eca3e84..e217da170f 100644 --- a/json/README.md +++ b/json/README.md @@ -5,3 +5,5 @@ ### Relevant Articles: - [Introduction to JSON Schema in Java](http://www.baeldung.com/introduction-to-json-schema-in-java) - [A Guide to FastJson](http://www.baeldung.com/????????) +- [Introduction to JSONForms](http://www.baeldung.com/introduction-to-jsonforms) +- [Introduction to JsonPath](http://www.baeldung.com/guide-to-jayway-jsonpath) diff --git a/json/src/main/webapp/index.html b/json/src/main/webapp/index.html new file mode 100644 index 0000000000..5c41c8a173 --- /dev/null +++ b/json/src/main/webapp/index.html @@ -0,0 +1,27 @@ + + + + Introduction to JSONForms + + + + + + +
+
+
+
+
+

Introduction to JSONForms

+
+
+ Bound data: {{data}} + +
+
+
+
+
+ + diff --git a/json/src/main/webapp/js/app.js b/json/src/main/webapp/js/app.js new file mode 100644 index 0000000000..484637bef4 --- /dev/null +++ b/json/src/main/webapp/js/app.js @@ -0,0 +1,15 @@ +'use strict'; + +var app = angular.module('jsonforms-intro', ['jsonforms']); +app.controller('MyController', ['$scope', 'Schema', 'UISchema', function($scope, Schema, UISchema) { + + $scope.schema = Schema; + + $scope.uiSchema = UISchema; + + $scope.data = { + "id": 1, + "name": "Lampshade", + "price": 1.85 + }; +}]); diff --git a/json/src/main/webapp/js/schema.js b/json/src/main/webapp/js/schema.js new file mode 100644 index 0000000000..34025868b9 --- /dev/null +++ b/json/src/main/webapp/js/schema.js @@ -0,0 +1,27 @@ +'use strict'; + +var app = angular.module('jsonforms-intro'); +app.value('Schema', + { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Product", + "description": "A product from the catalog", + "type": "object", + "properties": { + "id": { + "description": "The unique identifier for a product", + "type": "integer" + }, + "name": { + "description": "Name of the product", + "type": "string" + }, + "price": { + "type": "number", + "minimum": 0, + "exclusiveMinimum": true + } + }, + "required": ["id", "name", "price"] + } +); diff --git a/json/src/main/webapp/js/ui-schema.js b/json/src/main/webapp/js/ui-schema.js new file mode 100644 index 0000000000..aea5ac79c0 --- /dev/null +++ b/json/src/main/webapp/js/ui-schema.js @@ -0,0 +1,22 @@ +'use strict'; + +var app = angular.module('jsonforms-intro'); +app.value('UISchema', + { + "type": "HorizontalLayout", + "elements": [ + { + "type": "Control", + "scope": { "$ref": "#/properties/id" } + }, + { + "type": "Control", + "scope": { "$ref": "#/properties/name" } + }, + { + "type": "Control", + "scope": { "$ref": "#/properties/price" } + }, + ] + } +); diff --git a/json/src/main/webapp/package.json b/json/src/main/webapp/package.json new file mode 100644 index 0000000000..2f2d6c9ffa --- /dev/null +++ b/json/src/main/webapp/package.json @@ -0,0 +1,11 @@ +{ + "name": "jsonforms-intro", + "description": "Introduction to JSONForms", + "version": "0.0.1", + "license": "MIT", + "dependencies": { + "typings": "0.6.5", + "jsonforms": "0.0.19", + "bootstrap": "3.3.6" + } +} \ No newline at end of file diff --git a/junit5/REDAME.md b/junit5/REDAME.md new file mode 100644 index 0000000000..d4e30cd257 --- /dev/null +++ b/junit5/REDAME.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [The Basics of JUnit 5 – A Preview](http://www.baeldung.com/junit-5-preview) diff --git a/junit5/src/test/java/com/baeldung/FirstTest.java b/junit5/src/test/java/com/baeldung/FirstTest.java index 4fc6037174..3306dc01f9 100644 --- a/junit5/src/test/java/com/baeldung/FirstTest.java +++ b/junit5/src/test/java/com/baeldung/FirstTest.java @@ -19,6 +19,7 @@ class FirstTest { .sum() > 5, "Sum should be greater than 5"); } + @Disabled("test to show MultipleFailuresError") @Test void groupAssertions() { int[] numbers = {0, 1, 2, 3, 4}; diff --git a/log4j/README.md b/log4j/README.md new file mode 100644 index 0000000000..7355372f23 --- /dev/null +++ b/log4j/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Introduction to Java Logging](http://www.baeldung.com/java-logging-intro) diff --git a/log4j/pom.xml b/log4j/pom.xml index 76c05b36c1..ab384d4dd1 100644 --- a/log4j/pom.xml +++ b/log4j/pom.xml @@ -16,29 +16,25 @@ 1.2.17 - org.apache.logging.log4j log4j-api - 2.6 + 2.7 org.apache.logging.log4j log4j-core - 2.6 + 2.7 - - + com.lmax disruptor 3.3.4 - - ch.qos.logback logback-classic diff --git a/log4j/src/main/java/com/baeldung/slf4j/Slf4jExample.java b/log4j/src/main/java/com/baeldung/slf4j/Slf4jExample.java new file mode 100644 index 0000000000..6ecc7b887a --- /dev/null +++ b/log4j/src/main/java/com/baeldung/slf4j/Slf4jExample.java @@ -0,0 +1,20 @@ +package com.baeldung.slf4j; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * To switch between logging frameworks you need only to uncomment needed framework dependencies in pom.xml + */ +public class Slf4jExample { + private static Logger logger = LoggerFactory.getLogger(Slf4jExample.class); + + public static void main(String[] args) { + logger.debug("Debug log message"); + logger.info("Info log message"); + logger.error("Error log message"); + + String variable = "Hello John"; + logger.debug("Printing variable value {} ", variable); + } +} diff --git a/lombok/README.md b/lombok/README.md new file mode 100644 index 0000000000..4dc1c2d09d --- /dev/null +++ b/lombok/README.md @@ -0,0 +1,2 @@ +## Relevant Articles: +- [Introduction to Project Lombok](http://www.baeldung.com/intro-to-project-lombok) diff --git a/mapstruct/pom.xml b/mapstruct/pom.xml new file mode 100644 index 0000000000..aaa3e95f8c --- /dev/null +++ b/mapstruct/pom.xml @@ -0,0 +1,108 @@ + + + 4.0.0 + mapstruct + mapstruct + com.baeldung + 1.0 + jar + + + 1.0.0.Final + + + + org.mapstruct + mapstruct-jdk8 + ${org.mapstruct.version} + + + junit + junit + 4.12 + test + + + org.springframework + spring-context + 4.3.2.RELEASE + + + org.springframework + spring-test + 4.3.2.RELEASE + test + + + + mapstruct + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + diff --git a/mapstruct/src/main/java/com/baeldung/dto/DivisionDTO.java b/mapstruct/src/main/java/com/baeldung/dto/DivisionDTO.java new file mode 100644 index 0000000000..37f8bd111b --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/dto/DivisionDTO.java @@ -0,0 +1,33 @@ +package com.baeldung.dto; + +public class DivisionDTO { + + public DivisionDTO() { + } + + public DivisionDTO(int id, String name) { + super(); + this.id = id; + this.name = name; + } + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/mapstruct/src/main/java/com/baeldung/dto/EmployeeDTO.java b/mapstruct/src/main/java/com/baeldung/dto/EmployeeDTO.java new file mode 100644 index 0000000000..5da3165683 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/dto/EmployeeDTO.java @@ -0,0 +1,42 @@ +package com.baeldung.dto; + +public class EmployeeDTO { + + private int employeeId; + private String employeeName; + private DivisionDTO division; + private String employeeStartDt; + + public int getEmployeeId() { + return employeeId; + } + + public void setEmployeeId(int employeeId) { + this.employeeId = employeeId; + } + + public String getEmployeeName() { + return employeeName; + } + + public void setEmployeeName(String employeeName) { + this.employeeName = employeeName; + } + + public DivisionDTO getDivision() { + return division; + } + + public void setDivision(DivisionDTO division) { + this.division = division; + } + + public String getEmployeeStartDt() { + return employeeStartDt; + } + + public void setEmployeeStartDt(String employeeStartDt) { + this.employeeStartDt = employeeStartDt; + } + +} diff --git a/mapstruct/src/main/java/com/baeldung/dto/SimpleSource.java b/mapstruct/src/main/java/com/baeldung/dto/SimpleSource.java new file mode 100644 index 0000000000..ec8d80c4af --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/dto/SimpleSource.java @@ -0,0 +1,24 @@ +package com.baeldung.dto; + +public class SimpleSource { + + private String name; + private String description; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/mapstruct/src/main/java/com/baeldung/entity/Division.java b/mapstruct/src/main/java/com/baeldung/entity/Division.java new file mode 100644 index 0000000000..7b1416d6c5 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/entity/Division.java @@ -0,0 +1,33 @@ +package com.baeldung.entity; + +public class Division { + + public Division() { + } + + public Division(int id, String name) { + super(); + this.id = id; + this.name = name; + } + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/mapstruct/src/main/java/com/baeldung/entity/Employee.java b/mapstruct/src/main/java/com/baeldung/entity/Employee.java new file mode 100644 index 0000000000..04044f4dfe --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/entity/Employee.java @@ -0,0 +1,44 @@ +package com.baeldung.entity; + +import java.util.Date; + +public class Employee { + + private int id; + private String name; + private Division division; + private Date startDt; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Division getDivision() { + return division; + } + + public void setDivision(Division division) { + this.division = division; + } + + public Date getStartDt() { + return startDt; + } + + public void setStartDt(Date startDt) { + this.startDt = startDt; + } + +} diff --git a/mapstruct/src/main/java/com/baeldung/entity/SimpleDestination.java b/mapstruct/src/main/java/com/baeldung/entity/SimpleDestination.java new file mode 100644 index 0000000000..d9cba1c372 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/entity/SimpleDestination.java @@ -0,0 +1,24 @@ +package com.baeldung.entity; + +public class SimpleDestination { + + private String name; + private String description; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/mapstruct/src/main/java/com/baeldung/mapper/EmployeeMapper.java b/mapstruct/src/main/java/com/baeldung/mapper/EmployeeMapper.java new file mode 100644 index 0000000000..8e00103d0e --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapper/EmployeeMapper.java @@ -0,0 +1,30 @@ +package com.baeldung.mapper; + +import com.baeldung.dto.DivisionDTO; +import com.baeldung.dto.EmployeeDTO; +import com.baeldung.entity.Division; +import com.baeldung.entity.Employee; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; + +import java.util.List; + +@Mapper +public interface EmployeeMapper { + + @Mappings({ @Mapping(target = "employeeId", source = "entity.id"), @Mapping(target = "employeeName", source = "entity.name"), @Mapping(target = "employeeStartDt", source = "entity.startDt", dateFormat = "dd-MM-yyyy HH:mm:ss") }) + EmployeeDTO employeeToEmployeeDTO(Employee entity); + + @Mappings({ @Mapping(target = "id", source = "dto.employeeId"), @Mapping(target = "name", source = "dto.employeeName"), @Mapping(target = "startDt", source = "dto.employeeStartDt", dateFormat = "dd-MM-yyyy HH:mm:ss") }) + Employee employeeDTOtoEmployee(EmployeeDTO dto); + + DivisionDTO divisionToDivisionDTO(Division entity); + + Division divisionDTOtoDivision(DivisionDTO dto); + + List convertEmployeeDTOListToEmployeeList(List list); + + List convertEmployeeListToEmployeeDTOList(List list); + +} diff --git a/mapstruct/src/main/java/com/baeldung/mapper/SimpleSourceDestinationMapper.java b/mapstruct/src/main/java/com/baeldung/mapper/SimpleSourceDestinationMapper.java new file mode 100644 index 0000000000..f3f2187c20 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapper/SimpleSourceDestinationMapper.java @@ -0,0 +1,14 @@ +package com.baeldung.mapper; + +import com.baeldung.dto.SimpleSource; +import com.baeldung.entity.SimpleDestination; +import org.mapstruct.Mapper; + +@Mapper(componentModel = "spring") +public interface SimpleSourceDestinationMapper { + + SimpleDestination sourceToDestination(SimpleSource source); + + SimpleSource destinationToSource(SimpleDestination destination); + +} diff --git a/mapstruct/src/main/resources/applicationContext.xml b/mapstruct/src/main/resources/applicationContext.xml new file mode 100644 index 0000000000..22d8d1b769 --- /dev/null +++ b/mapstruct/src/main/resources/applicationContext.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/mapstruct/src/test/java/com/baeldung/mapper/EmployeeMapperTest.java b/mapstruct/src/test/java/com/baeldung/mapper/EmployeeMapperTest.java new file mode 100644 index 0000000000..7da6c41dc1 --- /dev/null +++ b/mapstruct/src/test/java/com/baeldung/mapper/EmployeeMapperTest.java @@ -0,0 +1,123 @@ +package com.baeldung.mapper; + +import com.baeldung.dto.DivisionDTO; +import com.baeldung.dto.EmployeeDTO; +import com.baeldung.entity.Division; +import com.baeldung.entity.Employee; +import org.junit.Test; +import org.mapstruct.factory.Mappers; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class EmployeeMapperTest { + + EmployeeMapper mapper = Mappers.getMapper(EmployeeMapper.class); + + private static final String DATE_FORMAT = "dd-MM-yyyy HH:mm:ss"; + + @Test + public void givenEmployeeDTOwithDiffNametoEmployee_whenMaps_thenCorrect() { + EmployeeDTO dto = new EmployeeDTO(); + dto.setEmployeeId(1); + dto.setEmployeeName("John"); + + Employee entity = mapper.employeeDTOtoEmployee(dto); + + assertEquals(dto.getEmployeeId(), entity.getId()); + assertEquals(dto.getEmployeeName(), entity.getName()); + } + + @Test + public void givenEmployeewithDiffNametoEmployeeDTO_whenMaps_thenCorrect() { + Employee entity = new Employee(); + entity.setId(1); + entity.setName("John"); + + EmployeeDTO dto = mapper.employeeToEmployeeDTO(entity); + + assertEquals(dto.getEmployeeId(), entity.getId()); + assertEquals(dto.getEmployeeName(), entity.getName()); + } + + @Test + public void givenEmployeeDTOwithNestedMappingToEmployee_whenMaps_thenCorrect() { + EmployeeDTO dto = new EmployeeDTO(); + dto.setDivision(new DivisionDTO(1, "Division1")); + + Employee entity = mapper.employeeDTOtoEmployee(dto); + + assertEquals(dto.getDivision().getId(), entity.getDivision().getId()); + assertEquals(dto.getDivision().getName(), entity.getDivision().getName()); + } + + @Test + public void givenEmployeeWithNestedMappingToEmployeeDTO_whenMaps_thenCorrect() { + Employee entity = new Employee(); + entity.setDivision(new Division(1, "Division1")); + + EmployeeDTO dto = mapper.employeeToEmployeeDTO(entity); + + assertEquals(dto.getDivision().getId(), entity.getDivision().getId()); + assertEquals(dto.getDivision().getName(), entity.getDivision().getName()); + } + + @Test + public void givenEmployeeListToEmployeeDTOList_whenMaps_thenCorrect() { + List employeeList = new ArrayList<>(); + Employee emp = new Employee(); + emp.setId(1); + emp.setName("EmpName"); + emp.setDivision(new Division(1, "Division1")); + employeeList.add(emp); + + List employeeDtoList = mapper.convertEmployeeListToEmployeeDTOList(employeeList); + EmployeeDTO employeeDTO = employeeDtoList.get(0); + assertEquals(employeeDTO.getEmployeeId(), emp.getId()); + assertEquals(employeeDTO.getEmployeeName(), emp.getName()); + assertEquals(employeeDTO.getDivision().getId(), emp.getDivision().getId()); + assertEquals(employeeDTO.getDivision().getName(), emp.getDivision().getName()); + } + + @Test + public void givenEmployeeDTOListToEmployeeList_whenMaps_thenCorrect() { + List employeeDTOList = new ArrayList<>(); + EmployeeDTO empDTO = new EmployeeDTO(); + empDTO.setEmployeeId(1); + empDTO.setEmployeeName("EmpName"); + empDTO.setDivision(new DivisionDTO(1, "Division1")); + employeeDTOList.add(empDTO); + + List employeeList = mapper.convertEmployeeDTOListToEmployeeList(employeeDTOList); + Employee employee = employeeList.get(0); + assertEquals(employee.getId(), empDTO.getEmployeeId()); + assertEquals(employee.getName(), empDTO.getEmployeeName()); + assertEquals(employee.getDivision().getId(), empDTO.getDivision().getId()); + assertEquals(employee.getDivision().getName(), empDTO.getDivision().getName()); + } + + @Test + public void givenEmployeeWithStartDateMappingToEmployeeDTO_whenMaps_thenCorrect() throws ParseException { + Employee entity = new Employee(); + entity.setStartDt(new Date()); + + EmployeeDTO dto = mapper.employeeToEmployeeDTO(entity); + SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT); + assertEquals(format.parse(dto.getEmployeeStartDt()).toString(), entity.getStartDt().toString()); + } + + @Test + public void givenEmployeeDTOWithStartDateMappingToEmployee_whenMaps_thenCorrect() throws ParseException { + EmployeeDTO dto = new EmployeeDTO(); + dto.setEmployeeStartDt("01-04-2016 01:00:00"); + + Employee entity = mapper.employeeDTOtoEmployee(dto); + SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT); + assertEquals(format.parse(dto.getEmployeeStartDt()).toString(), entity.getStartDt().toString()); + } +} diff --git a/mapstruct/src/test/java/com/baeldung/mapper/SimpleSourceDestinationMapperIntegrationTest.java b/mapstruct/src/test/java/com/baeldung/mapper/SimpleSourceDestinationMapperIntegrationTest.java new file mode 100644 index 0000000000..31d60c0d7d --- /dev/null +++ b/mapstruct/src/test/java/com/baeldung/mapper/SimpleSourceDestinationMapperIntegrationTest.java @@ -0,0 +1,44 @@ +package com.baeldung.mapper; + +import static org.junit.Assert.assertEquals; + +import com.baeldung.dto.SimpleSource; +import com.baeldung.entity.SimpleDestination; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:applicationContext.xml") +public class SimpleSourceDestinationMapperIntegrationTest { + + @Autowired + SimpleSourceDestinationMapper simpleSourceDestinationMapper; + + @Test + public void givenSimpleSourceToSimpleDestination_whenMaps_thenCorrect() { + SimpleSource simpleSource = new SimpleSource(); + simpleSource.setName("SourceName"); + simpleSource.setDescription("SourceDescription"); + + SimpleDestination destination = simpleSourceDestinationMapper.sourceToDestination(simpleSource); + + assertEquals(simpleSource.getName(), destination.getName()); + assertEquals(simpleSource.getDescription(), destination.getDescription()); + } + + @Test + public void givenSimpleDestinationToSourceDestination_whenMaps_thenCorrect() { + SimpleDestination destination = new SimpleDestination(); + destination.setName("DestinationName"); + destination.setDescription("DestinationDescription"); + + SimpleSource source = simpleSourceDestinationMapper.destinationToSource(destination); + + assertEquals(destination.getName(), source.getName()); + assertEquals(destination.getDescription(), source.getDescription()); + } + +} diff --git a/mockito/README.md b/mockito/README.md index 5e7cd19f78..6de2fb0c7a 100644 --- a/mockito/README.md +++ b/mockito/README.md @@ -8,3 +8,5 @@ - [Mockito When/Then Cookbook](http://www.baeldung.com/mockito-behavior) - [Mockito – Using Spies](http://www.baeldung.com/mockito-spy) - [Mockito – @Mock, @Spy, @Captor and @InjectMocks](http://www.baeldung.com/mockito-annotations) +- [Mockito’s Mock Methods](http://www.baeldung.com/mockito-mock-methods) +- [Introduction to PowerMock](http://www.baeldung.com/intro-to-powermock) diff --git a/mocks/jmockit/README.md b/mocks/jmockit/README.md index d04a07fdc5..3063fdc31d 100644 --- a/mocks/jmockit/README.md +++ b/mocks/jmockit/README.md @@ -6,3 +6,5 @@ ### Relevant Articles: - [JMockit 101](http://www.baeldung.com/jmockit-101) - [A Guide to JMockit Expectations](http://www.baeldung.com/jmockit-expectations) +- [JMockit Advanced Topics](http://www.baeldung.com/jmockit-advanced-topics) +- [JMockit Advanced Usage](http://www.baeldung.com/jmockit-advanced-usage) diff --git a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java new file mode 100644 index 0000000000..4d25f466a6 --- /dev/null +++ b/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java @@ -0,0 +1,20 @@ +package org.baeldung.mocks.jmockit; + +public class AdvancedCollaborator { + int i; + private int privateField = 5; + public AdvancedCollaborator(){} + public AdvancedCollaborator(String string) throws Exception{ + i = string.length(); + } + public String methodThatCallsPrivateMethod(int i){ + return privateMethod() + i; + } + public int methodThatReturnsThePrivateField(){ + return privateField; + } + private String privateMethod(){ + return "default:"; + } + class InnerAdvancedCollaborator{} +} diff --git a/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorTest.java b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorTest.java new file mode 100644 index 0000000000..aaabe44f66 --- /dev/null +++ b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorTest.java @@ -0,0 +1,110 @@ +package org.baeldung.mocks.jmockit; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.ArrayList; +import java.util.List; + +import org.baeldung.mocks.jmockit.AdvancedCollaborator.InnerAdvancedCollaborator; +import org.junit.Test; +import org.junit.runner.RunWith; + +import mockit.Deencapsulation; +import mockit.Expectations; +import mockit.Invocation; +import mockit.Mock; +import mockit.MockUp; +import mockit.Mocked; +import mockit.Tested; +import mockit.integration.junit4.JMockit; + +@RunWith(JMockit.class) +public class AdvancedCollaboratorTest & Comparable>> { + + @Tested + private AdvancedCollaborator mock; + + @Mocked + private MultiMock multiMock; + + @Test + public void testToMockUpPrivateMethod() { + new MockUp() { + @Mock + private String privateMethod() { + return "mocked: "; + } + }; + String res = mock.methodThatCallsPrivateMethod(1); + assertEquals("mocked: 1", res); + } + + @Test + public void testToMockUpDifficultConstructor() throws Exception { + new MockUp() { + @Mock + public void $init(Invocation invocation, String string) { + ((AdvancedCollaborator) invocation.getInvokedInstance()).i = 1; + } + }; + AdvancedCollaborator coll = new AdvancedCollaborator(null); + assertEquals(1, coll.i); + } + + @Test + public void testToCallPrivateMethodsDirectly() { + Object value = Deencapsulation.invoke(mock, "privateMethod"); + assertEquals("default:", value); + } + + @Test + public void testToSetPrivateFieldDirectly() { + Deencapsulation.setField(mock, "privateField", 10); + assertEquals(10, mock.methodThatReturnsThePrivateField()); + } + + @Test + public void testToGetPrivateFieldDirectly() { + int value = Deencapsulation.getField(mock, "privateField"); + assertEquals(5, value); + } + + @Test + public void testToCreateNewInstanceDirectly() { + AdvancedCollaborator coll = Deencapsulation.newInstance(AdvancedCollaborator.class, "foo"); + assertEquals(3, coll.i); + } + + @Test + public void testToCreateNewInnerClassInstanceDirectly() { + InnerAdvancedCollaborator innerCollaborator = Deencapsulation.newInnerInstance(InnerAdvancedCollaborator.class, mock); + assertNotNull(innerCollaborator); + } + + @Test + @SuppressWarnings("unchecked") + public void testMultipleInterfacesWholeTest() { + new Expectations() { + { + multiMock.get(5); result = "foo"; + multiMock.compareTo((List) any); result = 0; + } + }; + assertEquals("foo", multiMock.get(5)); + assertEquals(0, multiMock.compareTo(new ArrayList<>())); + } + + @Test + @SuppressWarnings("unchecked") + public & Comparable>> void testMultipleInterfacesOneMethod(@Mocked M mock) { + new Expectations() { + { + mock.get(5); result = "foo"; + mock.compareTo((List) any); + result = 0; } + }; + assertEquals("foo", mock.get(5)); + assertEquals(0, mock.compareTo(new ArrayList<>())); + } +} diff --git a/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingTest.java b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingTest.java new file mode 100644 index 0000000000..729cb30cd2 --- /dev/null +++ b/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingTest.java @@ -0,0 +1,57 @@ +package org.baeldung.mocks.jmockit; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import mockit.Expectations; +import mockit.Injectable; +import mockit.Mocked; +import mockit.Tested; +import mockit.Verifications; +import mockit.integration.junit4.JMockit; + +@RunWith(JMockit.class) +public class ReusingTest { + + @Injectable + private Collaborator collaborator; + + @Mocked + private Model model; + + @Tested + private Performer performer; + + @Before + public void setup(){ + new Expectations(){{ + model.getInfo(); result = "foo"; minTimes = 0; + collaborator.collaborate("foo"); result = true; minTimes = 0; + }}; + } + + @Test + public void testWithSetup() { + performer.perform(model); + verifyTrueCalls(1); + } + + protected void verifyTrueCalls(int calls){ + new Verifications(){{ + collaborator.receive(true); times = calls; + }}; + } + + final class TrueCallsVerification extends Verifications{ + public TrueCallsVerification(int calls){ + collaborator.receive(true); times = calls; + } + } + + @Test + public void testWithFinalClass() { + performer.perform(model); + new TrueCallsVerification(1); + } +} diff --git a/mutation-testing/pom.xml b/mutation-testing/pom.xml deleted file mode 100644 index 83012ab8fe..0000000000 --- a/mutation-testing/pom.xml +++ /dev/null @@ -1,38 +0,0 @@ - - 4.0.0 - com.baeldung - mutation-testing - 0.1-SNAPSHOT - mutation-testing - - - org.pitest - pitest-parent - 1.1.10 - pom - - - junit - junit - 4.9 - - - - - - org.pitest - pitest-maven - 1.1.10 - - - com.baeldung.testing.mutation.* - - - com.baeldung.mutation.test.* - - - - - - \ No newline at end of file diff --git a/orika/README.md b/orika/README.md new file mode 100644 index 0000000000..4ed033c170 --- /dev/null +++ b/orika/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Mapping with Orika](http://www.baeldung.com/orika-mapping) diff --git a/orika/pom.xml b/orika/pom.xml new file mode 100644 index 0000000000..c335b0dc22 --- /dev/null +++ b/orika/pom.xml @@ -0,0 +1,60 @@ + + 4.0.0 + com.baeldung + orika + 1.0 + + + 1.7.5 + 1.7.5 + 1.4.6 + 4.3 + + + Orika + + + + + org.slf4j + slf4j-api + ${slf4j-api.version} + + + + org.slf4j + jcl-over-slf4j + ${jcl-over-slf4j.version} + + + + ma.glasnost.orika + orika-core + ${orika-core.version} + + + + junit + junit + ${junit.version} + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 7 + 7 + + + + + + diff --git a/orika/src/main/java/com/baeldung/orika/Dest.java b/orika/src/main/java/com/baeldung/orika/Dest.java new file mode 100644 index 0000000000..4f050230ce --- /dev/null +++ b/orika/src/main/java/com/baeldung/orika/Dest.java @@ -0,0 +1,37 @@ +package com.baeldung.orika; + +public class Dest { + @Override + public String toString() { + return "Dest [name=" + name + ", age=" + age + "]"; + } + + private String name; + private int age; + + public Dest() { + + } + + public Dest(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/gson-jackson-performance/src/main/java/com/baeldung/pojo/simple/Customer.java b/orika/src/main/java/com/baeldung/orika/Name.java similarity index 65% rename from gson-jackson-performance/src/main/java/com/baeldung/pojo/simple/Customer.java rename to orika/src/main/java/com/baeldung/orika/Name.java index 3d5668f85a..fcf0214548 100644 --- a/gson-jackson-performance/src/main/java/com/baeldung/pojo/simple/Customer.java +++ b/orika/src/main/java/com/baeldung/orika/Name.java @@ -1,13 +1,13 @@ -package com.baeldung.pojo.simple; - - -public class Customer { +package com.baeldung.orika; +public class Name { private String firstName; - private String lastName; - private int age; + public Name(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } public String getFirstName() { return firstName; @@ -25,12 +25,4 @@ public class Customer { this.lastName = lastName; } - public int getAge() { - return age; - } - - public void setAge(int age) { - this.age = age; - } - } diff --git a/orika/src/main/java/com/baeldung/orika/Person.java b/orika/src/main/java/com/baeldung/orika/Person.java new file mode 100644 index 0000000000..90ae8dee5e --- /dev/null +++ b/orika/src/main/java/com/baeldung/orika/Person.java @@ -0,0 +1,48 @@ +package com.baeldung.orika; + +public class Person { + @Override + public String toString() { + return "Person [name=" + name + ", nickname=" + nickname + ", age=" + + age + "]"; + } + + private String name; + private String nickname; + private int age; + + public Person() { + + } + + public Person(String name, String nickname, int age) { + this.name = name; + this.nickname = nickname; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/orika/src/main/java/com/baeldung/orika/Person3.java b/orika/src/main/java/com/baeldung/orika/Person3.java new file mode 100644 index 0000000000..8661edfc10 --- /dev/null +++ b/orika/src/main/java/com/baeldung/orika/Person3.java @@ -0,0 +1,38 @@ +package com.baeldung.orika; + +public class Person3 { + private String name; + private String dtob; + + public Person3() { + + } + + public Person3(String name, String dtob) { + this.name = name; + this.dtob = dtob; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDtob() { + return dtob; + } + + public void setDtob(String dtob) { + this.dtob = dtob; + } + + @Override + public String toString() { + return "Person3 [name=" + name + ", dtob=" + dtob + "]"; + } + + +} diff --git a/orika/src/main/java/com/baeldung/orika/PersonContainer.java b/orika/src/main/java/com/baeldung/orika/PersonContainer.java new file mode 100644 index 0000000000..aaec136bb9 --- /dev/null +++ b/orika/src/main/java/com/baeldung/orika/PersonContainer.java @@ -0,0 +1,18 @@ +package com.baeldung.orika; + +public class PersonContainer { + private Name name; + + public PersonContainer(Name name) { + this.name = name; + } + + public Name getName() { + return name; + } + + public void setName(Name name) { + this.name = name; + } + +} diff --git a/orika/src/main/java/com/baeldung/orika/PersonCustomMapper.java b/orika/src/main/java/com/baeldung/orika/PersonCustomMapper.java new file mode 100644 index 0000000000..d839eea30e --- /dev/null +++ b/orika/src/main/java/com/baeldung/orika/PersonCustomMapper.java @@ -0,0 +1,36 @@ +package com.baeldung.orika; + +import ma.glasnost.orika.CustomMapper; +import ma.glasnost.orika.MappingContext; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +class PersonCustomMapper extends CustomMapper { + + @Override + public void mapAtoB(Personne3 a, Person3 b, MappingContext context) { + Date date = new Date(a.getDtob()); + DateFormat format = new SimpleDateFormat( + "yyyy-MM-dd'T'HH:mm:ss'Z'"); + String isoDate = format.format(date); + b.setDtob(isoDate); + } + + @Override + public void mapBtoA(Person3 b, Personne3 a, MappingContext context) { + DateFormat format = new SimpleDateFormat( + "yyyy-MM-dd'T'HH:mm:ss'Z'"); + Date date = null; + try { + date = format.parse(b.getDtob()); + + } catch (ParseException e) { + e.printStackTrace(); + } + long timestamp = date.getTime(); + a.setDtob(timestamp); + } +} diff --git a/orika/src/main/java/com/baeldung/orika/PersonListContainer.java b/orika/src/main/java/com/baeldung/orika/PersonListContainer.java new file mode 100644 index 0000000000..97ae15eb48 --- /dev/null +++ b/orika/src/main/java/com/baeldung/orika/PersonListContainer.java @@ -0,0 +1,20 @@ +package com.baeldung.orika; + +import java.util.List; + +public class PersonListContainer { + private List names; + + public PersonListContainer(List names) { + this.names = names; + } + + public List getNames() { + return names; + } + + public void setNames(List names) { + this.names = names; + } + +} diff --git a/orika/src/main/java/com/baeldung/orika/PersonNameArray.java b/orika/src/main/java/com/baeldung/orika/PersonNameArray.java new file mode 100644 index 0000000000..f2e98be537 --- /dev/null +++ b/orika/src/main/java/com/baeldung/orika/PersonNameArray.java @@ -0,0 +1,18 @@ +package com.baeldung.orika; + +public class PersonNameArray { + private String[] nameArray; + + public PersonNameArray(String[] nameArray) { + this.nameArray = nameArray; + } + + public String[] getNameArray() { + return nameArray; + } + + public void setNameArray(String[] nameArray) { + this.nameArray = nameArray; + } + +} diff --git a/orika/src/main/java/com/baeldung/orika/PersonNameList.java b/orika/src/main/java/com/baeldung/orika/PersonNameList.java new file mode 100644 index 0000000000..70798ebd35 --- /dev/null +++ b/orika/src/main/java/com/baeldung/orika/PersonNameList.java @@ -0,0 +1,20 @@ +package com.baeldung.orika; + +import java.util.List; + +public class PersonNameList { + private List nameList; + + public PersonNameList(List nameList) { + this.nameList = nameList; + } + + public List getNameList() { + return nameList; + } + + public void setNameList(List nameList) { + this.nameList = nameList; + } + +} diff --git a/orika/src/main/java/com/baeldung/orika/PersonNameMap.java b/orika/src/main/java/com/baeldung/orika/PersonNameMap.java new file mode 100644 index 0000000000..8126cdfc3a --- /dev/null +++ b/orika/src/main/java/com/baeldung/orika/PersonNameMap.java @@ -0,0 +1,20 @@ +package com.baeldung.orika; + +import java.util.Map; + +public class PersonNameMap { + private Map nameMap; + + public PersonNameMap(Map nameMap) { + this.nameMap = nameMap; + } + + public Map getNameMap() { + return nameMap; + } + + public void setNameMap(Map nameList) { + this.nameMap = nameList; + } + +} diff --git a/orika/src/main/java/com/baeldung/orika/PersonNameParts.java b/orika/src/main/java/com/baeldung/orika/PersonNameParts.java new file mode 100644 index 0000000000..7cfdcdd75b --- /dev/null +++ b/orika/src/main/java/com/baeldung/orika/PersonNameParts.java @@ -0,0 +1,28 @@ +package com.baeldung.orika; + +public class PersonNameParts { + private String firstName; + private String lastName; + + public PersonNameParts(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + +} diff --git a/orika/src/main/java/com/baeldung/orika/Personne.java b/orika/src/main/java/com/baeldung/orika/Personne.java new file mode 100644 index 0000000000..47789dd323 --- /dev/null +++ b/orika/src/main/java/com/baeldung/orika/Personne.java @@ -0,0 +1,44 @@ +package com.baeldung.orika; + +public class Personne { + private String nom; + private String surnom; + private int age; + + public Personne(String nom, String surnom, int age) { + this.nom = nom; + this.surnom = surnom; + this.age = age; + } + + public String getNom() { + return nom; + } + + public void setNom(String nom) { + this.nom = nom; + } + + public String getSurnom() { + return surnom; + } + + public void setSurnom(String surnom) { + this.surnom = surnom; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + @Override + public String toString() { + return "Personne [nom=" + nom + ", surnom=" + surnom + ", age=" + age + + "]"; + } + +} diff --git a/orika/src/main/java/com/baeldung/orika/Personne3.java b/orika/src/main/java/com/baeldung/orika/Personne3.java new file mode 100644 index 0000000000..35323c612a --- /dev/null +++ b/orika/src/main/java/com/baeldung/orika/Personne3.java @@ -0,0 +1,37 @@ +package com.baeldung.orika; + +public class Personne3 { + private String name; + private long dtob; + + public Personne3() { + + } + + public Personne3(String name, long dtob) { + this.name = name; + this.dtob = dtob; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getDtob() { + return dtob; + } + + public void setDtob(long dtob) { + this.dtob = dtob; + } + + @Override + public String toString() { + return "Personne3 [name=" + name + ", dtob=" + dtob + "]"; + } + +} diff --git a/orika/src/main/java/com/baeldung/orika/Source.java b/orika/src/main/java/com/baeldung/orika/Source.java new file mode 100644 index 0000000000..a973bab388 --- /dev/null +++ b/orika/src/main/java/com/baeldung/orika/Source.java @@ -0,0 +1,36 @@ +package com.baeldung.orika; + +public class Source { + @Override + public String toString() { + return "Source [name=" + name + ", age=" + age + "]"; + } + + private String name; + private int age; + + public Source() { + } + + public Source(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/orika/src/test/java/com/baeldung/orika/OrikaTest.java b/orika/src/test/java/com/baeldung/orika/OrikaTest.java new file mode 100644 index 0000000000..18dfcfa44e --- /dev/null +++ b/orika/src/test/java/com/baeldung/orika/OrikaTest.java @@ -0,0 +1,367 @@ +package com.baeldung.orika; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import ma.glasnost.orika.BoundMapperFacade; +import ma.glasnost.orika.CustomMapper; +import ma.glasnost.orika.MapperFacade; +import ma.glasnost.orika.MapperFactory; +import ma.glasnost.orika.MappingContext; +import ma.glasnost.orika.impl.DefaultMapperFactory; + +import org.junit.Before; +import org.junit.Test; + +public class OrikaTest { + MapperFactory mapperFactory; + CustomMapper customMapper; + // constant to help us cover time zone differences + private final long GMT_DIFFERENCE = 46800000; + + @Before + public void before() { + mapperFactory = new DefaultMapperFactory.Builder().build(); + customMapper = new PersonCustomMapper(); + } + + @Test + public void givenSrcAndDest_whenMaps_thenCorrect() { + mapperFactory.classMap(Source.class, Dest.class); + MapperFacade mapper = mapperFactory.getMapperFacade(); + Source src = new Source("Baeldung", 10); + Dest dest = mapper.map(src, Dest.class); + assertEquals(dest.getAge(), src.getAge()); + assertEquals(dest.getName(), src.getName()); + } + + @Test + public void givenSrcAndDest_whenMapsReverse_thenCorrect() { + mapperFactory.classMap(Source.class, Dest.class).byDefault(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + Dest src = new Dest("Baeldung", 10); + Source dest = mapper.map(src, Source.class); + assertEquals(dest.getAge(), src.getAge()); + assertEquals(dest.getName(), src.getName()); + } + + @Test + public void givenSrcAndDest_whenMapsByObject_thenCorrect() { + mapperFactory.classMap(Source.class, Dest.class).byDefault(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + Source src = new Source("Baeldung", 10); + Dest dest = new Dest(); + mapper.map(src, dest); + assertEquals(dest.getAge(), src.getAge()); + assertEquals(dest.getName(), src.getName()); + } + + @Test + public void givenSrcAndDest_whenMapsUsingBoundMapper_thenCorrect() { + BoundMapperFacade boundMapper = mapperFactory + .getMapperFacade(Source.class, Dest.class); + Source src = new Source("baeldung", 10); + Dest dest = boundMapper.map(src); + assertEquals(dest.getAge(), src.getAge()); + assertEquals(dest.getName(), src.getName()); + } + + @Test + public void givenSrcAndDest_whenMapsUsingBoundMapperInReverse_thenCorrect() { + BoundMapperFacade boundMapper = mapperFactory + .getMapperFacade(Source.class, Dest.class); + Dest src = new Dest("baeldung", 10); + Source dest = boundMapper.mapReverse(src); + assertEquals(dest.getAge(), src.getAge()); + assertEquals(dest.getName(), src.getName()); + } + + @Test + public void givenSrcAndDest_whenMapsUsingBoundMapperByObject_thenCorrect() { + BoundMapperFacade boundMapper = mapperFactory + .getMapperFacade(Source.class, Dest.class); + Source src = new Source("baeldung", 10); + Dest dest = new Dest(); + boundMapper.map(src, dest); + assertEquals(dest.getAge(), src.getAge()); + assertEquals(dest.getName(), src.getName()); + } + + @Test + public void givenSrcAndDest_whenMapsUsingBoundMapperByObjectInReverse_thenCorrect() { + BoundMapperFacade boundMapper = mapperFactory + .getMapperFacade(Source.class, Dest.class); + Dest src = new Dest("baeldung", 10); + Source dest = new Source(); + boundMapper.mapReverse(src, dest); + assertEquals(dest.getAge(), src.getAge()); + assertEquals(dest.getName(), src.getName()); + } + + @Test + public void givenSrcAndDestWithDifferentFieldNames_whenMaps_thenCorrect() { + mapperFactory.classMap(Personne.class, Person.class) + .field("nom", "name").field("surnom", "nickname") + .field("age", "age").register(); + + MapperFacade mapper = mapperFactory.getMapperFacade(); + + Personne frenchPerson = new Personne("Claire", "cla", 25); + Person englishPerson = mapper.map(frenchPerson, Person.class); + + assertEquals(englishPerson.getName(), frenchPerson.getNom()); + assertEquals(englishPerson.getNickname(), frenchPerson.getSurnom()); + assertEquals(englishPerson.getAge(), frenchPerson.getAge()); + + } + + @Test + public void givenBothDifferentAndSameFieldNames_whenFailsToMapSameNameFieldAutomatically_thenCorrect() { + mapperFactory.classMap(Personne.class, Person.class) + .field("nom", "name").field("surnom", "nickname").register(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + Personne frenchPerson = new Personne("Claire", "cla", 25); + + Person englishPerson = mapper.map(frenchPerson, Person.class); + assertFalse(englishPerson.getAge() == frenchPerson.getAge()); + + } + + @Test + public void givenBothDifferentAndSameFieldNames_whenMapsSameNameFieldByDefault_thenCorrect() { + mapperFactory.classMap(Personne.class, Person.class) + .field("nom", "name").field("surnom", "nickname").byDefault() + .register(); + + MapperFacade mapper = mapperFactory.getMapperFacade(); + Personne frenchPerson = new Personne("Claire", "cla", 25); + + Person englishPerson = mapper.map(frenchPerson, Person.class); + assertEquals(englishPerson.getName(), frenchPerson.getNom()); + assertEquals(englishPerson.getNickname(), frenchPerson.getSurnom()); + assertEquals(englishPerson.getAge(), frenchPerson.getAge()); + + } + + @Test + public void givenUnidirectionalMappingSetup_whenMapsUnidirectionally_thenCorrect() { + mapperFactory.classMap(Personne.class, Person.class) + .fieldAToB("nom", "name").fieldAToB("surnom", "nickname") + .fieldAToB("age", "age").register(); + ; + MapperFacade mapper = mapperFactory.getMapperFacade(); + Personne frenchPerson = new Personne("Claire", "cla", 25); + + Person englishPerson = mapper.map(frenchPerson, Person.class); + assertEquals(englishPerson.getName(), frenchPerson.getNom()); + assertEquals(englishPerson.getNickname(), frenchPerson.getSurnom()); + assertEquals(englishPerson.getAge(), frenchPerson.getAge()); + + } + + + @Test + public void givenSrcAndDest_whenCanExcludeField_thenCorrect() { + mapperFactory.classMap(Personne.class, Person.class).exclude("nom") + .field("surnom", "nickname").field("age", "age").register(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + + Personne frenchPerson = new Personne("Claire", "cla", 25); + Person englishPerson = mapper.map(frenchPerson, Person.class); + + assertEquals(null, englishPerson.getName()); + assertEquals(englishPerson.getNickname(), frenchPerson.getSurnom()); + assertEquals(englishPerson.getAge(), frenchPerson.getAge()); + } + + @Test + public void givenSpecificConstructorToUse_whenMaps_thenCorrect() { + mapperFactory.classMap(Personne.class, Person.class).constructorB() + .field("nom", "name").field("surnom", "nickname") + .field("age", "age").register(); + ; + MapperFacade mapper = mapperFactory.getMapperFacade(); + Personne frenchPerson = new Personne("Claire", "cla", 25); + + Person englishPerson = mapper.map(frenchPerson, Person.class); + assertEquals(englishPerson.getName(), frenchPerson.getNom()); + assertEquals(englishPerson.getNickname(), frenchPerson.getSurnom()); + assertEquals(englishPerson.getAge(), frenchPerson.getAge()); + + } + + @Test + public void givenSrcWithListAndDestWithPrimitiveAttributes_whenMaps_thenCorrect() { + mapperFactory.classMap(PersonNameList.class, PersonNameParts.class) + .field("nameList[0]", "firstName") + .field("nameList[1]", "lastName").register(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + List nameList = Arrays.asList(new String[]{"Sylvester", + "Stallone"}); + PersonNameList src = new PersonNameList(nameList); + PersonNameParts dest = mapper.map(src, PersonNameParts.class); + assertEquals(dest.getFirstName(), "Sylvester"); + assertEquals(dest.getLastName(), "Stallone"); + } + + @Test + public void givenSrcWithArrayAndDestWithPrimitiveAttributes_whenMaps_thenCorrect() { + mapperFactory.classMap(PersonNameArray.class, PersonNameParts.class) + .field("nameArray[0]", "firstName") + .field("nameArray[1]", "lastName").register(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + String[] nameArray = new String[]{"Vin", "Diesel"}; + PersonNameArray src = new PersonNameArray(nameArray); + PersonNameParts dest = mapper.map(src, PersonNameParts.class); + assertEquals(dest.getFirstName(), "Vin"); + assertEquals(dest.getLastName(), "Diesel"); + } + + @Test + public void givenSrcWithMapAndDestWithPrimitiveAttributes_whenMaps_thenCorrect() { + mapperFactory.classMap(PersonNameMap.class, PersonNameParts.class) + .field("nameMap['first']", "firstName") + .field("nameMap[\"last\"]", "lastName").register(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + Map nameMap = new HashMap<>(); + nameMap.put("first", "Leornado"); + nameMap.put("last", "DiCaprio"); + PersonNameMap src = new PersonNameMap(nameMap); + PersonNameParts dest = mapper.map(src, PersonNameParts.class); + assertEquals(dest.getFirstName(), "Leornado"); + assertEquals(dest.getLastName(), "DiCaprio"); + } + + @Test + public void givenSrcWithNestedFields_whenMaps_thenCorrect() { + mapperFactory.classMap(PersonContainer.class, PersonNameParts.class) + .field("name.firstName", "firstName") + .field("name.lastName", "lastName").register(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + PersonContainer src = new PersonContainer(new Name("Nick", "Canon")); + PersonNameParts dest = mapper.map(src, PersonNameParts.class); + assertEquals(dest.getFirstName(), "Nick"); + assertEquals(dest.getLastName(), "Canon"); + } + + @Test + public void givenSrcWithNullField_whenMapsThenCorrect() { + mapperFactory.classMap(Source.class, Dest.class).byDefault(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + Source src = new Source(null, 10); + Dest dest = mapper.map(src, Dest.class); + assertEquals(dest.getAge(), src.getAge()); + assertEquals(dest.getName(), src.getName()); + } + + @Test + public void givenSrcWithNullAndGlobalConfigForNoNull_whenFailsToMap_ThenCorrect() { + MapperFactory mapperFactory = new DefaultMapperFactory.Builder() + .mapNulls(false).build(); + mapperFactory.classMap(Source.class, Dest.class); + MapperFacade mapper = mapperFactory.getMapperFacade(); + Source src = new Source(null, 10); + Dest dest = new Dest("Clinton", 55); + mapper.map(src, dest); + assertEquals(dest.getAge(), src.getAge()); + assertEquals(dest.getName(), "Clinton"); + } + + @Test + public void givenSrcWithNullAndLocalConfigForNoNull_whenFailsToMap_ThenCorrect() { + mapperFactory.classMap(Source.class, Dest.class).field("age", "age") + .mapNulls(false).field("name", "name").byDefault().register(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + Source src = new Source(null, 10); + Dest dest = new Dest("Clinton", 55); + mapper.map(src, dest); + assertEquals(dest.getAge(), src.getAge()); + assertEquals(dest.getName(), "Clinton"); + } + + @Test + public void givenDestWithNullReverseMappedToSource_whenMapsByDefault_thenCorrect() { + mapperFactory.classMap(Source.class, Dest.class).byDefault(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + Dest src = new Dest(null, 10); + Source dest = new Source("Vin", 44); + mapper.map(src, dest); + assertEquals(dest.getAge(), src.getAge()); + assertEquals(dest.getName(), src.getName()); + } + + @Test + public void givenDestWithNullReverseMappedToSourceAndLocalConfigForNoNull_whenFailsToMap_thenCorrect() { + mapperFactory.classMap(Source.class, Dest.class).field("age", "age") + .mapNullsInReverse(false).field("name", "name").byDefault() + .register(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + Dest src = new Dest(null, 10); + Source dest = new Source("Vin", 44); + mapper.map(src, dest); + assertEquals(dest.getAge(), src.getAge()); + assertEquals(dest.getName(), "Vin"); + } + + @Test + public void givenSrcWithNullAndFieldLevelConfigForNoNull_whenFailsToMap_ThenCorrect() { + mapperFactory.classMap(Source.class, Dest.class).field("age", "age") + .fieldMap("name", "name").mapNulls(false).add().byDefault() + .register(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + Source src = new Source(null, 10); + Dest dest = new Dest("Clinton", 55); + mapper.map(src, dest); + assertEquals(dest.getAge(), src.getAge()); + assertEquals(dest.getName(), "Clinton"); + } + + @Test + public void givenSrcAndDest_whenCustomMapperWorks_thenCorrect() { + mapperFactory.classMap(Personne3.class, Person3.class) + .customize(customMapper).register(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + long timestamp = new Long("1182882159000"); + Personne3 personne3 = new Personne3("Leornardo", timestamp); + Person3 person3 = mapper.map(personne3, Person3.class); + + String timestampTest = person3.getDtob(); + // since different timezones will resolve the timestamp to a different + // datetime string, it suffices to check only for format rather than + // specific date + assertTrue(timestampTest.charAt(10) == 'T' + && timestampTest.charAt(19) == 'Z'); + } + + @Test + public void givenSrcAndDest_whenCustomMapperWorksBidirectionally_thenCorrect() { + mapperFactory.classMap(Personne3.class, Person3.class) + .customize(customMapper).register(); + MapperFacade mapper = mapperFactory.getMapperFacade(); + + String dateTime = "2007-06-26T21:22:39Z"; + long timestamp = new Long("1182882159000"); + Person3 person3 = new Person3("Leornardo", dateTime); + Personne3 personne3 = mapper.map(person3, Personne3.class); + long timestampToTest = personne3.getDtob(); + /* + * since different timezones will resolve the datetime to a different + * unix timestamp, we must provide a range of tolerance + */ + assertTrue(timestampToTest == timestamp + || timestampToTest >= timestamp - GMT_DIFFERENCE + || timestampToTest <= timestamp + GMT_DIFFERENCE); + + } + +} diff --git a/patterns/front-controller/pom.xml b/patterns/front-controller/pom.xml new file mode 100644 index 0000000000..2dabf484e1 --- /dev/null +++ b/patterns/front-controller/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + front-controller + war + + + patterns-parent + com.baeldung.patterns + 1.0.0-SNAPSHOT + .. + + + + + javax.servlet + javax.servlet-api + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-war-plugin + + + org.eclipse.jetty + jetty-maven-plugin + + + /front-controller + + + + + + diff --git a/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/FrontControllerServlet.java b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/FrontControllerServlet.java new file mode 100644 index 0000000000..9fb120399c --- /dev/null +++ b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/FrontControllerServlet.java @@ -0,0 +1,38 @@ +package com.baeldung.patterns.front.controller; + +import com.baeldung.patterns.front.controller.commands.FrontCommand; +import com.baeldung.patterns.front.controller.commands.UnknownCommand; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class FrontControllerServlet extends HttpServlet { + @Override + protected void doGet( + HttpServletRequest request, + HttpServletResponse response + ) throws ServletException, IOException { + FrontCommand command = getCommand(request); + command.init(getServletContext(), request, response); + command.process(); + } + + private FrontCommand getCommand(HttpServletRequest request) { + try { + Class type = Class.forName( + String.format( + "com.baeldung.patterns.front.controller.commands.%sCommand", + request.getParameter("command") + ) + ); + return (FrontCommand) type + .asSubclass(FrontCommand.class) + .newInstance(); + } catch (Exception e) { + return new UnknownCommand(); + } + } +} diff --git a/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/commands/FrontCommand.java b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/commands/FrontCommand.java new file mode 100644 index 0000000000..cc92731050 --- /dev/null +++ b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/commands/FrontCommand.java @@ -0,0 +1,32 @@ +package com.baeldung.patterns.front.controller.commands; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public abstract class FrontCommand { + protected ServletContext context; + protected HttpServletRequest request; + protected HttpServletResponse response; + + public void init( + ServletContext servletContext, + HttpServletRequest servletRequest, + HttpServletResponse servletResponse + ) { + this.context = servletContext; + this.request = servletRequest; + this.response = servletResponse; + } + + public abstract void process() throws ServletException, IOException; + + protected void forward(String target) throws ServletException, IOException { + target = String.format("/WEB-INF/jsp/%s.jsp", target); + RequestDispatcher dispatcher = context.getRequestDispatcher(target); + dispatcher.forward(request, response); + } +} diff --git a/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/commands/SearchCommand.java b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/commands/SearchCommand.java new file mode 100644 index 0000000000..21028b07f0 --- /dev/null +++ b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/commands/SearchCommand.java @@ -0,0 +1,21 @@ +package com.baeldung.patterns.front.controller.commands; + +import com.baeldung.patterns.front.controller.data.Book; +import com.baeldung.patterns.front.controller.data.BookshelfImpl; + +import javax.servlet.ServletException; +import java.io.IOException; + +public class SearchCommand extends FrontCommand { + @Override + public void process() throws ServletException, IOException { + Book book = new BookshelfImpl().getInstance() + .findByTitle(request.getParameter("title")); + if (book != null) { + request.setAttribute("book", book); + forward("book-found"); + } else { + forward("book-notfound"); + } + } +} diff --git a/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/commands/UnknownCommand.java b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/commands/UnknownCommand.java new file mode 100644 index 0000000000..9f24746598 --- /dev/null +++ b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/commands/UnknownCommand.java @@ -0,0 +1,11 @@ +package com.baeldung.patterns.front.controller.commands; + +import javax.servlet.ServletException; +import java.io.IOException; + +public class UnknownCommand extends FrontCommand { + @Override + public void process() throws ServletException, IOException { + forward("unknown"); + } +} diff --git a/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/data/Book.java b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/data/Book.java new file mode 100644 index 0000000000..5a15df92c4 --- /dev/null +++ b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/data/Book.java @@ -0,0 +1,15 @@ +package com.baeldung.patterns.front.controller.data; + +public interface Book { + String getAuthor(); + + void setAuthor(String author); + + String getTitle(); + + void setTitle(String title); + + Double getPrice(); + + void setPrice(Double price); +} diff --git a/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/data/BookImpl.java b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/data/BookImpl.java new file mode 100644 index 0000000000..0421ff5623 --- /dev/null +++ b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/data/BookImpl.java @@ -0,0 +1,46 @@ +package com.baeldung.patterns.front.controller.data; + +public class BookImpl implements Book { + private String author; + private String title; + private Double price; + + public BookImpl() { + } + + public BookImpl(String author, String title, Double price) { + this.author = author; + this.title = title; + this.price = price; + } + + @Override + public String getAuthor() { + return author; + } + + @Override + public void setAuthor(String author) { + this.author = author; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public void setTitle(String title) { + this.title = title; + } + + @Override + public Double getPrice() { + return price; + } + + @Override + public void setPrice(Double price) { + this.price = price; + } +} diff --git a/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/data/Bookshelf.java b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/data/Bookshelf.java new file mode 100644 index 0000000000..21e3067133 --- /dev/null +++ b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/data/Bookshelf.java @@ -0,0 +1,15 @@ +package com.baeldung.patterns.front.controller.data; + +public interface Bookshelf { + + default void init() { + add(new BookImpl("Wilson, Robert Anton & Shea, Robert", "Illuminati", 9.99)); + add(new BookImpl("Fowler, Martin", "Patterns of Enterprise Application Architecture", 27.88)); + } + + Bookshelf getInstance(); + + boolean add(E book); + + Book findByTitle(String title); +} diff --git a/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/data/BookshelfImpl.java b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/data/BookshelfImpl.java new file mode 100644 index 0000000000..dd1fa4e523 --- /dev/null +++ b/patterns/front-controller/src/main/java/com/baeldung/patterns/front/controller/data/BookshelfImpl.java @@ -0,0 +1,24 @@ +package com.baeldung.patterns.front.controller.data; + +import java.util.ArrayList; + +public class BookshelfImpl extends ArrayList implements Bookshelf { + private static Bookshelf INSTANCE; + + @Override + public Bookshelf getInstance() { + if (INSTANCE == null) { + INSTANCE = new BookshelfImpl(); + INSTANCE.init(); + } + return INSTANCE; + } + + @Override + public Book findByTitle(String title) { + return this.stream() + .filter(book -> book.getTitle().toLowerCase().contains(title.toLowerCase())) + .findFirst() + .orElse(null); + } +} diff --git a/patterns/front-controller/src/main/resources/front controller.png b/patterns/front-controller/src/main/resources/front controller.png new file mode 100644 index 0000000000..bd475bf3f3 Binary files /dev/null and b/patterns/front-controller/src/main/resources/front controller.png differ diff --git a/patterns/front-controller/src/main/resources/front controller.puml b/patterns/front-controller/src/main/resources/front controller.puml new file mode 100644 index 0000000000..fbd4f416ef --- /dev/null +++ b/patterns/front-controller/src/main/resources/front controller.puml @@ -0,0 +1,22 @@ +@startuml + +class Handler { +doGet +doPost +} + +abstract class AbstractCommand { +process +} +class ConcreteCommand1 { +process +} +class ConcreteCommand2 { +process +} + +Handler .right.> AbstractCommand +AbstractCommand <|-- ConcreteCommand1 +AbstractCommand <|-- ConcreteCommand2 + +@enduml \ No newline at end of file diff --git a/patterns/front-controller/src/main/webapp/WEB-INF/jsp/book-found.jsp b/patterns/front-controller/src/main/webapp/WEB-INF/jsp/book-found.jsp new file mode 100644 index 0000000000..42e08b4a46 --- /dev/null +++ b/patterns/front-controller/src/main/webapp/WEB-INF/jsp/book-found.jsp @@ -0,0 +1,12 @@ + + + + Bookshelf: Title found + + +

Our Bookshelf contains this title:

+

${book.getTitle()}

+

Author: ${book.getAuthor()}

+ + + diff --git a/patterns/front-controller/src/main/webapp/WEB-INF/jsp/book-notfound.jsp b/patterns/front-controller/src/main/webapp/WEB-INF/jsp/book-notfound.jsp new file mode 100644 index 0000000000..2f8ac01755 --- /dev/null +++ b/patterns/front-controller/src/main/webapp/WEB-INF/jsp/book-notfound.jsp @@ -0,0 +1,10 @@ + + + + Bookshelf: Title not found + + +

Our Bookshelf doesn't contains this title:

+

${param.get("title")}

+ + diff --git a/patterns/front-controller/src/main/webapp/WEB-INF/jsp/unknown.jsp b/patterns/front-controller/src/main/webapp/WEB-INF/jsp/unknown.jsp new file mode 100644 index 0000000000..b52b2de8d5 --- /dev/null +++ b/patterns/front-controller/src/main/webapp/WEB-INF/jsp/unknown.jsp @@ -0,0 +1,9 @@ + + + + Bookshelf: Command unknown + + +

Sorry, this command is not known!

+ + diff --git a/patterns/front-controller/src/main/webapp/WEB-INF/web.xml b/patterns/front-controller/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..4abca2bb97 --- /dev/null +++ b/patterns/front-controller/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,15 @@ + + + + front-controller + com.baeldung.patterns.front.controller.FrontControllerServlet + + + front-controller + / + + diff --git a/patterns/intercepting-filter/pom.xml b/patterns/intercepting-filter/pom.xml new file mode 100644 index 0000000000..2cf89246f9 --- /dev/null +++ b/patterns/intercepting-filter/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + intercepting-filter + war + + + com.baeldung.patterns + patterns-parent + 1.0.0-SNAPSHOT + .. + + + + + javax.servlet + javax.servlet-api + + + org.slf4j + slf4j-api + 1.7.21 + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-war-plugin + + false + + + + org.eclipse.jetty + jetty-maven-plugin + + + / + + + + + + diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/FrontControllerServlet.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/FrontControllerServlet.java new file mode 100644 index 0000000000..9d8a004265 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/FrontControllerServlet.java @@ -0,0 +1,66 @@ +package com.baeldung.patterns.intercepting.filter; + +import com.baeldung.patterns.intercepting.filter.commands.FrontCommand; +import com.baeldung.patterns.intercepting.filter.commands.UnknownCommand; +import com.baeldung.patterns.intercepting.filter.data.Bookshelf; +import com.baeldung.patterns.intercepting.filter.data.BookshelfImpl; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@WebServlet(name = "intercepting-filter", urlPatterns = "/") +public class FrontControllerServlet extends HttpServlet { + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + Bookshelf bookshelf = new BookshelfImpl(); + bookshelf.init(); + getServletContext().setAttribute("bookshelf", bookshelf); + } + + @Override + protected void doGet( + HttpServletRequest request, + HttpServletResponse response + ) throws ServletException, IOException { + doCommand(request, response); + } + + @Override + protected void doPost( + HttpServletRequest request, + HttpServletResponse response + ) throws ServletException, IOException { + doCommand(request, response); + } + + private void doCommand( + HttpServletRequest request, + HttpServletResponse response + ) throws ServletException, IOException { + FrontCommand command = getCommand(request); + command.init(request, response); + command.process(); + } + + private FrontCommand getCommand(HttpServletRequest request) { + try { + Class type = Class.forName( + String.format( + "com.baeldung.patterns.intercepting.filter.commands.%sCommand", + request.getParameter("command") + ) + ); + return (FrontCommand) type + .asSubclass(FrontCommand.class) + .newInstance(); + } catch (Exception e) { + return new UnknownCommand(); + } + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/CheckoutCommand.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/CheckoutCommand.java new file mode 100644 index 0000000000..fda88c741e --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/CheckoutCommand.java @@ -0,0 +1,27 @@ +package com.baeldung.patterns.intercepting.filter.commands; + +import com.baeldung.patterns.intercepting.filter.data.Order; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpSession; +import java.io.IOException; + +public class CheckoutCommand extends FrontCommand { + @Override + public void process() throws ServletException, IOException { + super.process(); + HttpSession session = request.getSession(false); + if (request.getMethod().equals("POST")) { + session.removeAttribute("order"); + response.sendRedirect("/?command=Home&message=Thank you for buying!"); + } else { + Order order = (Order) session.getAttribute("order"); + Double total = order.getItems().entrySet().stream() + .map(entry -> entry.getKey().getPrice() * entry.getValue()) + .reduce((p1, p2) -> p1 + p2) + .orElse(0.00); + request.setAttribute("total", total); + forward("shopping-cart"); + } + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/FrontCommand.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/FrontCommand.java new file mode 100644 index 0000000000..a3c545703b --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/FrontCommand.java @@ -0,0 +1,43 @@ +package com.baeldung.patterns.intercepting.filter.commands; + +import com.baeldung.patterns.intercepting.filter.filters.FilterManager; +import com.baeldung.patterns.intercepting.filter.filters.OnIntercept; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public abstract class FrontCommand implements OnIntercept { + protected HttpServletRequest request; + protected HttpServletResponse response; + private boolean intercept; + + public FrontCommand() { + } + + public void init(HttpServletRequest request, HttpServletResponse response) { + this.request = request; + this.response = response; + } + + public void process() throws ServletException, IOException { + FilterManager.process(request, response, this); + } + + public void forward(String target) throws ServletException, IOException { + if (intercept) { + return; + } + String path = String.format("/WEB-INF/jsp/%s.jsp", target); + RequestDispatcher dispatcher = request.getServletContext() + .getRequestDispatcher(path); + dispatcher.forward(request, response); + } + + @Override + public void intercept() { + intercept = true; + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/HomeCommand.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/HomeCommand.java new file mode 100644 index 0000000000..33e60b44b5 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/HomeCommand.java @@ -0,0 +1,17 @@ +package com.baeldung.patterns.intercepting.filter.commands; + +import com.baeldung.patterns.intercepting.filter.data.Bookshelf; + +import javax.servlet.ServletException; +import java.io.IOException; + +public class HomeCommand extends FrontCommand { + @Override + public void process() throws ServletException, IOException { + super.process(); + Bookshelf bookshelf = (Bookshelf) request.getServletContext() + .getAttribute("bookshelf"); + request.setAttribute("books", bookshelf); + forward("home"); + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LoginCommand.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LoginCommand.java new file mode 100644 index 0000000000..46a0329112 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LoginCommand.java @@ -0,0 +1,23 @@ +package com.baeldung.patterns.intercepting.filter.commands; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.util.Optional; + +public class LoginCommand extends FrontCommand { + @Override + public void process() throws ServletException, IOException { + if (request.getMethod().equals("POST")) { + HttpSession session = request.getSession(true); + session.setAttribute("username", request.getParameter("username")); + response.sendRedirect(request.getParameter("redirect")); + } else { + String queryString = Optional.ofNullable(request.getQueryString()) + .orElse("command=Home"); + request.setAttribute("redirect", request.getRequestURL() + .append("?").append(queryString).toString()); + forward("login"); + } + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LogoutCommand.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LogoutCommand.java new file mode 100644 index 0000000000..f309dc5cf3 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/LogoutCommand.java @@ -0,0 +1,19 @@ +package com.baeldung.patterns.intercepting.filter.commands; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.util.Optional; + +public class LogoutCommand extends FrontCommand { + @Override + public void process() throws ServletException, IOException { + super.process(); + Optional.ofNullable(request.getSession(false)) + .ifPresent(session -> { + session.removeAttribute("username"); + session.removeAttribute("order"); + }); + response.sendRedirect("/?command=Home"); + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/OrderCommand.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/OrderCommand.java new file mode 100644 index 0000000000..a57785669b --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/OrderCommand.java @@ -0,0 +1,33 @@ +package com.baeldung.patterns.intercepting.filter.commands; + +import com.baeldung.patterns.intercepting.filter.data.Book; +import com.baeldung.patterns.intercepting.filter.data.Bookshelf; +import com.baeldung.patterns.intercepting.filter.data.Order; +import com.baeldung.patterns.intercepting.filter.data.OrderImpl; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.util.Optional; + +public class OrderCommand extends FrontCommand { + @Override + public void process() throws ServletException, IOException { + super.process(); + if (request.getMethod().equals("POST")) { + HttpSession session = request.getSession(false); + Order order = Optional + .ofNullable(session.getAttribute("order")) + .map(Order.class::cast) + .orElseGet(() -> new OrderImpl((String) session.getAttribute("username"))); + Bookshelf bookshelf = (Bookshelf) request.getServletContext() + .getAttribute("bookshelf"); + String isbn = request.getParameter("isbn"); + Integer quantity = Integer.parseInt(request.getParameter("quantity")); + Book book = bookshelf.get(isbn); + order.add(book, quantity); + session.setAttribute("order", order); + response.sendRedirect(String.format("/?command=Show&isbn=%s", isbn)); + } + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/SearchCommand.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/SearchCommand.java new file mode 100644 index 0000000000..6c52f4f5a9 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/SearchCommand.java @@ -0,0 +1,25 @@ +package com.baeldung.patterns.intercepting.filter.commands; + +import com.baeldung.patterns.intercepting.filter.data.Book; +import com.baeldung.patterns.intercepting.filter.data.Bookshelf; + +import javax.servlet.ServletException; +import java.io.IOException; +import java.util.List; + +public class SearchCommand extends FrontCommand { + @Override + public void process() throws ServletException, IOException { + super.process(); + Bookshelf bookshelf = (Bookshelf) request.getServletContext() + .getAttribute("bookshelf"); + String q = request.getParameter("q"); + List books = bookshelf.find(q); + if (books.size() > 0) { + request.setAttribute("books", books); + forward("book-found"); + } else { + forward("book-notfound"); + } + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/ShowCommand.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/ShowCommand.java new file mode 100644 index 0000000000..1ea5ca6edb --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/ShowCommand.java @@ -0,0 +1,21 @@ +package com.baeldung.patterns.intercepting.filter.commands; + +import com.baeldung.patterns.intercepting.filter.data.Book; +import com.baeldung.patterns.intercepting.filter.data.Bookshelf; + +import javax.servlet.ServletException; +import java.io.IOException; +import java.util.Collections; + +public class ShowCommand extends FrontCommand { + @Override + public void process() throws ServletException, IOException { + super.process(); + Bookshelf bookshelf = (Bookshelf) request.getServletContext() + .getAttribute("bookshelf"); + String title = request.getParameter("isbn"); + Book book = bookshelf.get(title); + request.setAttribute("books", Collections.singletonList(book)); + forward("book-found"); + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/UnknownCommand.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/UnknownCommand.java new file mode 100644 index 0000000000..427efe5aba --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/commands/UnknownCommand.java @@ -0,0 +1,12 @@ +package com.baeldung.patterns.intercepting.filter.commands; + +import javax.servlet.ServletException; +import java.io.IOException; + +public class UnknownCommand extends FrontCommand { + @Override + public void process() throws ServletException, IOException { + super.process(); + forward("unknown"); + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/Book.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/Book.java new file mode 100644 index 0000000000..4e98095c2c --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/Book.java @@ -0,0 +1,19 @@ +package com.baeldung.patterns.intercepting.filter.data; + +public interface Book { + String getIsbn(); + + void setIsbn(String isbn); + + String getAuthor(); + + void setAuthor(String author); + + String getTitle(); + + void setTitle(String title); + + Double getPrice(); + + void setPrice(Double price); +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/BookImpl.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/BookImpl.java new file mode 100644 index 0000000000..cd0c0924e2 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/BookImpl.java @@ -0,0 +1,58 @@ +package com.baeldung.patterns.intercepting.filter.data; + +public class BookImpl implements Book { + private String isbn; + private String author; + private String title; + private Double price; + + public BookImpl() { + } + + public BookImpl(String isbn, String author, String title, Double price) { + this.isbn = isbn; + this.author = author; + this.title = title; + this.price = price; + } + + @Override + public String getIsbn() { + return isbn; + } + + @Override + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + @Override + public String getAuthor() { + return author; + } + + @Override + public void setAuthor(String author) { + this.author = author; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public void setTitle(String title) { + this.title = title; + } + + @Override + public Double getPrice() { + return price; + } + + @Override + public void setPrice(Double price) { + this.price = price; + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/Bookshelf.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/Bookshelf.java new file mode 100644 index 0000000000..26541de8e0 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/Bookshelf.java @@ -0,0 +1,18 @@ +package com.baeldung.patterns.intercepting.filter.data; + +import java.util.List; + +public interface Bookshelf { + + default void init() { + add(new BookImpl("001", "Wilson, Robert Anton & Shea, Robert", "Illuminati", 9.99)); + add(new BookImpl("002", "Fowler, Martin", "Patterns of Enterprise Application Architecture", 27.88)); + add(new BookImpl("003", "Unknown", "Something about German Umlauts (äüö) and ß", 5.49)); + } + + boolean add(E book); + + Book get(String isbn); + + List find(String q); +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/BookshelfImpl.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/BookshelfImpl.java new file mode 100644 index 0000000000..5767af8e50 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/BookshelfImpl.java @@ -0,0 +1,23 @@ +package com.baeldung.patterns.intercepting.filter.data; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class BookshelfImpl extends ArrayList implements Bookshelf { + @Override + public Book get(String isbn) { + return this.stream() + .filter(book -> book.getIsbn().equals(isbn)) + .findFirst() + .orElse(null); + } + + @Override + public List find(String q) { + return this.stream() + .filter(book -> book.getTitle().toLowerCase().contains(q.toLowerCase()) + || book.getAuthor().toLowerCase().contains(q.toLowerCase())) + .collect(Collectors.toList()); + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/Order.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/Order.java new file mode 100644 index 0000000000..f4a32002d7 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/Order.java @@ -0,0 +1,11 @@ +package com.baeldung.patterns.intercepting.filter.data; + +import java.util.Map; + +public interface Order { + String getUsername(); + + Map getItems(); + + void add(Book item, Integer quantity); +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/OrderImpl.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/OrderImpl.java new file mode 100644 index 0000000000..9f50e45082 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/data/OrderImpl.java @@ -0,0 +1,40 @@ +package com.baeldung.patterns.intercepting.filter.data; + +import java.util.HashMap; +import java.util.Map; + +public class OrderImpl implements Order { + private String username; + private Map items = new HashMap<>(); + + public OrderImpl(String username) { + this.username = username; + } + + @Override + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + @Override + public Map getItems() { + return items; + } + + public void setItems(Map items) { + this.items = items; + } + + @Override + public void add(Book item, Integer quantity) { + Integer q = 0; + if (this.items.containsKey(item)) { + q = this.items.get(item); + } + this.items.put(item, quantity + q); + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/AuthenticationFilter.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/AuthenticationFilter.java new file mode 100644 index 0000000000..a2cac9d84c --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/AuthenticationFilter.java @@ -0,0 +1,45 @@ +package com.baeldung.patterns.intercepting.filter.filters; + +import com.baeldung.patterns.intercepting.filter.commands.FrontCommand; +import com.baeldung.patterns.intercepting.filter.commands.LoginCommand; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; + +public class AuthenticationFilter implements Filter { + private OnIntercept callback; + + public AuthenticationFilter(OnIntercept callback) { + this.callback = callback; + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter( + ServletRequest request, + ServletResponse response, + FilterChain chain + ) throws IOException, ServletException { + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + HttpSession session = httpServletRequest.getSession(false); + if (session == null || session.getAttribute("username") == null) { + callback.intercept(); + FrontCommand command = new LoginCommand(); + command.init(httpServletRequest, httpServletResponse); + command.process(); + } else { + chain.doFilter(request, response); + } + } + + @Override + public void destroy() { + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/BaseFilter.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/BaseFilter.java new file mode 100644 index 0000000000..90d13a6eda --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/BaseFilter.java @@ -0,0 +1,25 @@ +package com.baeldung.patterns.intercepting.filter.filters; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.Filter; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; + +public abstract class BaseFilter implements Filter { + private static final Logger log = LoggerFactory.getLogger(BaseFilter.class); + + protected FilterConfig filterConfig; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + log.info("Initialize filter: {}", getClass().getSimpleName()); + this.filterConfig = filterConfig; + } + + @Override + public void destroy() { + log.info("Destroy filter: {}", getClass().getSimpleName()); + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/EncodingFilter.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/EncodingFilter.java new file mode 100644 index 0000000000..0806aecba3 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/EncodingFilter.java @@ -0,0 +1,34 @@ +package com.baeldung.patterns.intercepting.filter.filters; + +import javax.servlet.*; +import javax.servlet.annotation.WebFilter; +import javax.servlet.annotation.WebInitParam; +import java.io.IOException; +import java.util.Optional; + +@WebFilter( + servletNames = {"intercepting-filter"}, + initParams = {@WebInitParam(name = "encoding", value = "UTF-8")} +) +public class EncodingFilter extends BaseFilter { + private String encoding; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + super.init(filterConfig); + this.encoding = filterConfig.getInitParameter("encoding"); + } + + @Override + public void doFilter( + ServletRequest request, + ServletResponse response, + FilterChain chain + ) throws IOException, ServletException { + String encoding = Optional + .ofNullable(request.getParameter("encoding")) + .orElse(this.encoding); + response.setCharacterEncoding(encoding); + chain.doFilter(request, response); + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/FilterChainImpl.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/FilterChainImpl.java new file mode 100644 index 0000000000..80ddef785c --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/FilterChainImpl.java @@ -0,0 +1,25 @@ +package com.baeldung.patterns.intercepting.filter.filters; + +import javax.servlet.*; +import java.io.IOException; +import java.util.Arrays; +import java.util.Iterator; + +public class FilterChainImpl implements FilterChain { + private Iterator filters; + + public FilterChainImpl(Filter... filters) { + this.filters = Arrays.asList(filters).iterator(); + } + + @Override + public void doFilter( + ServletRequest request, + ServletResponse response + ) throws IOException, ServletException { + if (filters.hasNext()) { + Filter filter = filters.next(); + filter.doFilter(request, response, this); + } + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/FilterManager.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/FilterManager.java new file mode 100644 index 0000000000..2f7b7ac703 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/FilterManager.java @@ -0,0 +1,21 @@ +package com.baeldung.patterns.intercepting.filter.filters; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class FilterManager { + public static void process( + HttpServletRequest request, + HttpServletResponse response, + OnIntercept callback + ) throws ServletException, IOException { + FilterChain filterChain = new FilterChainImpl( + new AuthenticationFilter(callback), + new VisitorCounterFilter() + ); + filterChain.doFilter(request, response); + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/LoggingFilter.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/LoggingFilter.java new file mode 100644 index 0000000000..322592f84e --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/LoggingFilter.java @@ -0,0 +1,34 @@ +package com.baeldung.patterns.intercepting.filter.filters; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.Optional; + +@WebFilter(servletNames = "intercepting-filter") +public class LoggingFilter extends BaseFilter { + private static final Logger log = LoggerFactory.getLogger(LoggingFilter.class); + + @Override + public void doFilter( + ServletRequest request, + ServletResponse response, + FilterChain chain + ) throws IOException, ServletException { + chain.doFilter(request, response); + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + String username = Optional + .ofNullable(httpServletRequest.getAttribute("username")) + .map(Object::toString) + .orElse("guest"); + log.info("Request from '{}@{}': {}?{}", username, request.getRemoteAddr(), + httpServletRequest.getRequestURI(), request.getParameterMap()); + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/OnIntercept.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/OnIntercept.java new file mode 100644 index 0000000000..1a138f1e1c --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/OnIntercept.java @@ -0,0 +1,5 @@ +package com.baeldung.patterns.intercepting.filter.filters; + +public interface OnIntercept { + void intercept(); +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/TemplateFilter.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/TemplateFilter.java new file mode 100644 index 0000000000..64396ef931 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/TemplateFilter.java @@ -0,0 +1,34 @@ +package com.baeldung.patterns.intercepting.filter.filters; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public abstract class TemplateFilter extends BaseFilter { + protected abstract void preFilter( + HttpServletRequest request, + HttpServletResponse response + ) throws IOException, ServletException; + + protected abstract void postFilter( + HttpServletRequest request, + HttpServletResponse response + ) throws IOException, ServletException; + + @Override + public void doFilter( + ServletRequest request, + ServletResponse response, + FilterChain chain + ) throws IOException, ServletException { + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + preFilter(httpServletRequest, httpServletResponse); + chain.doFilter(request, response); + postFilter(httpServletRequest, httpServletResponse); + } +} diff --git a/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/VisitorCounterFilter.java b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/VisitorCounterFilter.java new file mode 100644 index 0000000000..42551310d3 --- /dev/null +++ b/patterns/intercepting-filter/src/main/java/com/baeldung/patterns/intercepting/filter/filters/VisitorCounterFilter.java @@ -0,0 +1,35 @@ +package com.baeldung.patterns.intercepting.filter.filters; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +public class VisitorCounterFilter implements Filter { + private static Set users = new HashSet<>(); + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter( + ServletRequest request, + ServletResponse response, + FilterChain chain + ) throws IOException, ServletException { + HttpSession session = ((HttpServletRequest) request).getSession(false); + Optional.ofNullable(session.getAttribute("username")) + .map(Object::toString) + .ifPresent(users::add); + request.setAttribute("counter", users.size()); + chain.doFilter(request, response); + } + + @Override + public void destroy() { + } +} diff --git a/patterns/intercepting-filter/src/main/resources/front_controller.png b/patterns/intercepting-filter/src/main/resources/front_controller.png new file mode 100644 index 0000000000..af22a38e37 Binary files /dev/null and b/patterns/intercepting-filter/src/main/resources/front_controller.png differ diff --git a/patterns/intercepting-filter/src/main/resources/front_controller.puml b/patterns/intercepting-filter/src/main/resources/front_controller.puml new file mode 100644 index 0000000000..cbc2dc8bd9 --- /dev/null +++ b/patterns/intercepting-filter/src/main/resources/front_controller.puml @@ -0,0 +1,22 @@ +@startuml +scale 1.5 +class Handler { +doGet +doPost +} + +abstract class AbstractCommand { +process +} +class ConcreteCommand1 { +process +} +class ConcreteCommand2 { +process +} + +Handler .right.> AbstractCommand +AbstractCommand <|-- ConcreteCommand1 +AbstractCommand <|-- ConcreteCommand2 + +@enduml \ No newline at end of file diff --git a/patterns/intercepting-filter/src/main/resources/intercepting_filter-custom_strategy.png b/patterns/intercepting-filter/src/main/resources/intercepting_filter-custom_strategy.png new file mode 100644 index 0000000000..2f025fad5e Binary files /dev/null and b/patterns/intercepting-filter/src/main/resources/intercepting_filter-custom_strategy.png differ diff --git a/patterns/intercepting-filter/src/main/resources/intercepting_filter-custom_strategy.puml b/patterns/intercepting-filter/src/main/resources/intercepting_filter-custom_strategy.puml new file mode 100644 index 0000000000..4090085d85 --- /dev/null +++ b/patterns/intercepting-filter/src/main/resources/intercepting_filter-custom_strategy.puml @@ -0,0 +1,29 @@ +@startuml +scale 1.5 + +class FrontControllerServlet { + void doGet() + void doPost() +} +class FilterManager { + {static} void process() +} +class FilterChainImpl { + void doFilter() +} +class AuthenticationFilter { + void doFilter() +} +class VisitorCounterFilter { + void doFilter() +} +class FrontCommand { + void process() +} + +FrontControllerServlet -- FrontCommand +FrontCommand .right.-- FilterManager +FilterManager -- FilterChainImpl +FilterChainImpl .right.-- AuthenticationFilter +AuthenticationFilter .right.-- VisitorCounterFilter +@enduml diff --git a/patterns/intercepting-filter/src/main/resources/intercepting_filter-standard_strategy.png b/patterns/intercepting-filter/src/main/resources/intercepting_filter-standard_strategy.png new file mode 100644 index 0000000000..0d8db711a7 Binary files /dev/null and b/patterns/intercepting-filter/src/main/resources/intercepting_filter-standard_strategy.png differ diff --git a/patterns/intercepting-filter/src/main/resources/intercepting_filter-standard_strategy.puml b/patterns/intercepting-filter/src/main/resources/intercepting_filter-standard_strategy.puml new file mode 100644 index 0000000000..1261d9ee4b --- /dev/null +++ b/patterns/intercepting-filter/src/main/resources/intercepting_filter-standard_strategy.puml @@ -0,0 +1,26 @@ +@startuml +scale 1.5 + +class FrontControllerServlet { + void doGet() + void doPost() +} +abstract class BaseFilter { + void init() + void destroy() +} +class LoggingFilter { + void doFilter() +} +class EncodingFilter { + void doFilter() +} +class FrontCommand { + void process() +} + +FrontControllerServlet .right.-- FrontCommand +FrontControllerServlet -- BaseFilter +BaseFilter <|-- LoggingFilter +BaseFilter <|-- EncodingFilter +@enduml diff --git a/patterns/intercepting-filter/src/main/resources/intercepting_filter-template_strategy.png b/patterns/intercepting-filter/src/main/resources/intercepting_filter-template_strategy.png new file mode 100644 index 0000000000..5c37aa2937 Binary files /dev/null and b/patterns/intercepting-filter/src/main/resources/intercepting_filter-template_strategy.png differ diff --git a/patterns/intercepting-filter/src/main/resources/intercepting_filter-template_strategy.puml b/patterns/intercepting-filter/src/main/resources/intercepting_filter-template_strategy.puml new file mode 100644 index 0000000000..77b001f547 --- /dev/null +++ b/patterns/intercepting-filter/src/main/resources/intercepting_filter-template_strategy.puml @@ -0,0 +1,25 @@ +@startuml +scale 1.5 + +class FrontControllerServlet { + void doGet() + void doPost() +} +abstract class BaseFilter { + void init() + void destroy() +} +abstract class TemplateFilter { + {abstract} void preFilter() + {abstract} void postFilter() + -- + void doFilter() +} +class FrontCommand { + void process() +} + +FrontControllerServlet .right.-- FrontCommand +FrontControllerServlet -- BaseFilter +BaseFilter <|-- TemplateFilter +@enduml diff --git a/patterns/intercepting-filter/src/main/resources/intercepting_filter.png b/patterns/intercepting-filter/src/main/resources/intercepting_filter.png new file mode 100644 index 0000000000..9ccacc8081 Binary files /dev/null and b/patterns/intercepting-filter/src/main/resources/intercepting_filter.png differ diff --git a/patterns/intercepting-filter/src/main/resources/intercepting_filter.puml b/patterns/intercepting-filter/src/main/resources/intercepting_filter.puml new file mode 100644 index 0000000000..b06b822323 --- /dev/null +++ b/patterns/intercepting-filter/src/main/resources/intercepting_filter.puml @@ -0,0 +1,17 @@ +@startuml +scale 1.5 + +class Client +class FilterManager +interface FilterChain +interface "Filter 1" +interface "Filter 2" +interface "Filter 3" + +Client .right.-- FilterManager +FilterManager .right.-- Target +FilterManager -- FilterChain +FilterChain .right.-- "Filter 3" +FilterChain .right.-- "Filter 2" +FilterChain .right.-- "Filter 1" +@enduml diff --git a/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/book-found.jsp b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/book-found.jsp new file mode 100644 index 0000000000..4de1d3ca23 --- /dev/null +++ b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/book-found.jsp @@ -0,0 +1,24 @@ +<%@ page import="com.baeldung.patterns.intercepting.filter.data.Book" %> +<%@ page import="java.util.List" %> + + + + Bookshelf: Title found + + +

Our Bookshelf contains following titles:

+ <% for (Book book : (List) request.getAttribute("books")) { %> +

<%= book.getTitle() %>

+

Author: <%= book.getAuthor() %>

+
+ + + + + Go back... +
+ <% } %> + <%@ include file="shopping-cart-hint.jsp"%> + <%@ include file="visitor-counter.jsp"%> + + diff --git a/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/book-notfound.jsp b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/book-notfound.jsp new file mode 100644 index 0000000000..284b1e4759 --- /dev/null +++ b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/book-notfound.jsp @@ -0,0 +1,11 @@ + + + + Bookshelf: Title not found + + +

Our Bookshelf doesn't contains this title:

+

<%= request.getParameter("q") %>

+ <%@ include file="visitor-counter.jsp"%> + + diff --git a/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/home.jsp b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/home.jsp new file mode 100644 index 0000000000..2c2d7c2f22 --- /dev/null +++ b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/home.jsp @@ -0,0 +1,27 @@ +<%@ page import="com.baeldung.patterns.intercepting.filter.data.Book" %> +<%@ page import="java.util.List" %> + + + + Bookshelf: Home + + +
+ + +
+ <% if (request.getParameter("message") != null) { %> +

<%= request.getParameter("message") %>

+ <% } else { %> +

Welcome to the Bookshelf!

+ <% } %> + <% for (Book book : (List) request.getAttribute("books")) { %> +
+

<%= book.getAuthor() %>:

+

<%= book.getTitle() %>

+ More... + <% } %> + <%@ include file="shopping-cart-hint.jsp"%> + <%@ include file="visitor-counter.jsp"%> + + diff --git a/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/login.jsp b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/login.jsp new file mode 100644 index 0000000000..619068bcae --- /dev/null +++ b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/login.jsp @@ -0,0 +1,16 @@ + + + + Bookshelf: Login + + +

Please input a username:

+

Login

+
+ + "> + +
+ <%@ include file="visitor-counter.jsp" %> + + diff --git a/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/shopping-cart-hint.jsp b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/shopping-cart-hint.jsp new file mode 100644 index 0000000000..7e0c051540 --- /dev/null +++ b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/shopping-cart-hint.jsp @@ -0,0 +1,16 @@ +<%@ page import="com.baeldung.patterns.intercepting.filter.data.Order" %> +<% if (session != null && session.getAttribute("order") != null) { %> + <% Order order = ((Order) session.getAttribute("order")); %> + <% if (order != null && order.getItems().size() > 0) { %> +
+

+ Your shopping cart is holding + <% if (order.getItems().size() == 1) { %> + 1 item. + <% } else { %> + <%= (order.getItems().size()) %> items. + <% } %> + Checkout +

+ <% } %> +<% } %> diff --git a/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/shopping-cart.jsp b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/shopping-cart.jsp new file mode 100644 index 0000000000..5f71d2e54e --- /dev/null +++ b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/shopping-cart.jsp @@ -0,0 +1,29 @@ +<%@ page import="com.baeldung.patterns.intercepting.filter.data.Book" %> +<%@ page import="com.baeldung.patterns.intercepting.filter.data.Order" %> +<%@ page import="java.util.Map" %> + + + + Bookshelf: Checkout + + +

You are about to buy the following books:

+

Shopping Cart

+ <% Order order = (Order) session.getAttribute("order"); %> +
    + <% for (Map.Entry entry : order.getItems().entrySet()) { %> +
  • + <%= entry.getValue() %> x <%= entry.getKey().getPrice() %> +

    <%= entry.getKey().getTitle() %>

    + by <%= entry.getKey().getAuthor()%> +
  • + <% } %> +
+

+ Total: <%= request.getAttribute("total") %> +

+
+ +
+ + diff --git a/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/unknown.jsp b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/unknown.jsp new file mode 100644 index 0000000000..b52b2de8d5 --- /dev/null +++ b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/unknown.jsp @@ -0,0 +1,9 @@ + + + + Bookshelf: Command unknown + + +

Sorry, this command is not known!

+ + diff --git a/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/visitor-counter.jsp b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/visitor-counter.jsp new file mode 100644 index 0000000000..de1c741fb1 --- /dev/null +++ b/patterns/intercepting-filter/src/main/webapp/WEB-INF/jsp/visitor-counter.jsp @@ -0,0 +1,5 @@ +<% Integer counter = (Integer) request.getAttribute("counter"); %> +<% if (counter != null && counter > 0) { %> +
+

You are visitor #<%= counter %>. Logout

+<% } %> diff --git a/patterns/pom.xml b/patterns/pom.xml new file mode 100644 index 0000000000..6797891353 --- /dev/null +++ b/patterns/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + com.baeldung.patterns + patterns-parent + pom + + front-controller + intercepting-filter + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + .. + + + + + + javax.servlet + javax.servlet-api + 3.1.0 + provided + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-war-plugin + 3.0.0 + + + org.eclipse.jetty + jetty-maven-plugin + 9.3.12.v20160915 + + + + + diff --git a/pdf/.gitignore b/pdf/.gitignore new file mode 100644 index 0000000000..b83d22266a --- /dev/null +++ b/pdf/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/pdf/pom.xml b/pdf/pom.xml new file mode 100644 index 0000000000..311265880d --- /dev/null +++ b/pdf/pom.xml @@ -0,0 +1,87 @@ + + + 4.0.0 + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + pdf + pdf + http://maven.apache.org + + + UTF-8 + 3.5.1 + + + + + junit + junit + 3.8.1 + test + + + org.apache.pdfbox + pdfbox-tools + 2.0.3 + + + net.sf.cssbox + pdf2dom + 1.6 + + + com.itextpdf + itextpdf + 5.5.10 + + + org.apache.poi + poi + 3.15 + + + org.apache.poi + poi-scratchpad + 3.15 + + + org.apache.xmlgraphics + batik-transcoder + 1.8 + + + org.apache.poi + poi-ooxml + 3.15 + + + + + pdf + + + src/main/resources + true + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + + + diff --git a/pdf/src/main/java/com/baeldung/pdf/PDF2HTMLExample.java b/pdf/src/main/java/com/baeldung/pdf/PDF2HTMLExample.java new file mode 100644 index 0000000000..0d38208bab --- /dev/null +++ b/pdf/src/main/java/com/baeldung/pdf/PDF2HTMLExample.java @@ -0,0 +1,35 @@ +package com.baeldung.pdf; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Writer; + +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.fit.pdfdom.PDFDomTree; + +public class PDF2HTMLExample { + + private static final String FILENAME = "src/main/resources/pdf.pdf"; + + public static void main(String[] args) { + try { + generateHTMLFromPDF(FILENAME); + } catch (IOException | ParserConfigurationException e) { + e.printStackTrace(); + } + } + + private static void generateHTMLFromPDF(String filename) throws ParserConfigurationException, IOException { + PDDocument pdf = PDDocument.load(new File(filename)); + PDFDomTree parser = new PDFDomTree(); + Writer output = new PrintWriter("src/output/pdf.html", "utf-8"); + parser.writeText(pdf, output); + output.close(); + if (pdf != null) { + pdf.close(); + } + } +} diff --git a/pdf/src/main/java/com/baeldung/pdf/PDF2ImageExample.java b/pdf/src/main/java/com/baeldung/pdf/PDF2ImageExample.java new file mode 100644 index 0000000000..00778d16c1 --- /dev/null +++ b/pdf/src/main/java/com/baeldung/pdf/PDF2ImageExample.java @@ -0,0 +1,35 @@ +package com.baeldung.pdf; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.rendering.ImageType; +import org.apache.pdfbox.rendering.PDFRenderer; +import org.apache.pdfbox.tools.imageio.ImageIOUtil; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +public class PDF2ImageExample { + + private static final String FILENAME = "src/main/resources/pdf.pdf"; + + public static void main(String[] args) { + try { + generateImageFromPDF(FILENAME, "png"); + generateImageFromPDF(FILENAME, "jpeg"); + generateImageFromPDF(FILENAME, "gif"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void generateImageFromPDF(String filename, String extension) throws IOException { + PDDocument document = PDDocument.load(new File(filename)); + PDFRenderer pdfRenderer = new PDFRenderer(document); + for (int page = 0; page < document.getNumberOfPages(); ++page) { + BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB); + ImageIOUtil.writeImage(bim, String.format("src/output/pdf-%d.%s", page + 1, extension), 300); + } + document.close(); + } +} diff --git a/pdf/src/main/java/com/baeldung/pdf/PDF2TextExample.java b/pdf/src/main/java/com/baeldung/pdf/PDF2TextExample.java new file mode 100644 index 0000000000..c5880a4e91 --- /dev/null +++ b/pdf/src/main/java/com/baeldung/pdf/PDF2TextExample.java @@ -0,0 +1,48 @@ +package com.baeldung.pdf; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; + +import org.apache.pdfbox.cos.COSDocument; +import org.apache.pdfbox.io.RandomAccessFile; +import org.apache.pdfbox.pdfparser.PDFParser; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.text.PDFTextStripper; + +public class PDF2TextExample { + + private static final String FILENAME = "src/main/resources/pdf.pdf"; + + public static void main(String[] args) { + try { + generateTxtFromPDF(FILENAME); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void generateTxtFromPDF(String filename) throws IOException { + File f = new File(filename); + String parsedText; + PDFParser parser = new PDFParser(new RandomAccessFile(f, "r")); + parser.parse(); + + COSDocument cosDoc = parser.getDocument(); + + PDFTextStripper pdfStripper = new PDFTextStripper(); + PDDocument pdDoc = new PDDocument(cosDoc); + + parsedText = pdfStripper.getText(pdDoc); + + if (cosDoc != null) + cosDoc.close(); + if (pdDoc != null) + pdDoc.close(); + + PrintWriter pw = new PrintWriter("src/output/pdf.txt"); + pw.print(parsedText); + pw.close(); + } + +} diff --git a/pdf/src/main/java/com/baeldung/pdf/PDF2WordExample.java b/pdf/src/main/java/com/baeldung/pdf/PDF2WordExample.java new file mode 100644 index 0000000000..1f416592ef --- /dev/null +++ b/pdf/src/main/java/com/baeldung/pdf/PDF2WordExample.java @@ -0,0 +1,50 @@ +package com.baeldung.pdf; + +import java.io.FileOutputStream; +import java.io.IOException; + +import org.apache.poi.xwpf.usermodel.BreakType; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFParagraph; +import org.apache.poi.xwpf.usermodel.XWPFRun; + +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.parser.PdfReaderContentParser; +import com.itextpdf.text.pdf.parser.SimpleTextExtractionStrategy; +import com.itextpdf.text.pdf.parser.TextExtractionStrategy; + +public class PDF2WordExample { + + private static final String FILENAME = "src/main/resources/pdf.pdf"; + + public static void main(String[] args) { + try { + generateDocFromPDF(FILENAME); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void generateDocFromPDF(String filename) throws IOException { + XWPFDocument doc = new XWPFDocument(); + + String pdf = filename; + PdfReader reader = new PdfReader(pdf); + PdfReaderContentParser parser = new PdfReaderContentParser(reader); + + for (int i = 1; i <= reader.getNumberOfPages(); i++) { + TextExtractionStrategy strategy = parser.processContent(i, new SimpleTextExtractionStrategy()); + String text = strategy.getResultantText(); + XWPFParagraph p = doc.createParagraph(); + XWPFRun run = p.createRun(); + run.setText(text); + run.addBreak(BreakType.PAGE); + } + FileOutputStream out = new FileOutputStream("src/output/pdf.docx"); + doc.write(out); + out.close(); + reader.close(); + doc.close(); + } + +} diff --git a/pdf/src/main/resources/pdf.pdf b/pdf/src/main/resources/pdf.pdf new file mode 100644 index 0000000000..f45d226b39 Binary files /dev/null and b/pdf/src/main/resources/pdf.pdf differ diff --git a/play-framework/introduction/.gitignore b/play-framework/introduction/.gitignore new file mode 100644 index 0000000000..eb372fc719 --- /dev/null +++ b/play-framework/introduction/.gitignore @@ -0,0 +1,8 @@ +logs +target +/.idea +/.idea_modules +/.classpath +/.project +/.settings +/RUNNING_PID diff --git a/play-framework/introduction/LICENSE b/play-framework/introduction/LICENSE new file mode 100644 index 0000000000..4baedcb95f --- /dev/null +++ b/play-framework/introduction/LICENSE @@ -0,0 +1,8 @@ +This software is licensed under the Apache 2 license, quoted below. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with +the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific +language governing permissions and limitations under the License. \ No newline at end of file diff --git a/play-framework/introduction/README b/play-framework/introduction/README new file mode 100644 index 0000000000..f21d092edf --- /dev/null +++ b/play-framework/introduction/README @@ -0,0 +1,49 @@ +This is your new Play application +================================= + +This file will be packaged with your application when using `activator dist`. + +There are several demonstration files available in this template. + +Controllers +=========== + +- HomeController.java: + + Shows how to handle simple HTTP requests. + +- AsyncController.java: + + Shows how to do asynchronous programming when handling a request. + +- CountController.java: + + Shows how to inject a component into a controller and use the component when + handling requests. + +Components +========== + +- Module.java: + + Shows how to use Guice to bind all the components needed by your application. + +- Counter.java: + + An example of a component that contains state, in this case a simple counter. + +- ApplicationTimer.java: + + An example of a component that starts when the application starts and stops + when the application stops. + +Filters +======= + +- Filters.java: + + Creates the list of HTTP filters used by your application. + +- ExampleFilter.java + + A simple filter that adds a header to every response. \ No newline at end of file diff --git a/play-framework/introduction/app/Filters.java b/play-framework/introduction/app/Filters.java new file mode 100644 index 0000000000..255de8ca93 --- /dev/null +++ b/play-framework/introduction/app/Filters.java @@ -0,0 +1,46 @@ +import javax.inject.*; +import play.*; +import play.mvc.EssentialFilter; +import play.http.HttpFilters; +import play.mvc.*; + +import filters.ExampleFilter; + +/** + * This class configures filters that run on every request. This + * class is queried by Play to get a list of filters. + * + * Play will automatically use filters from any class called + * Filters that is placed the root package. You can load filters + * from a different class by adding a `play.http.filters` setting to + * the application.conf configuration file. + */ +@Singleton +public class Filters implements HttpFilters { + + private final Environment env; + private final EssentialFilter exampleFilter; + + /** + * @param env Basic environment settings for the current application. + * @param exampleFilter A demonstration filter that adds a header to + */ + @Inject + public Filters(Environment env, ExampleFilter exampleFilter) { + this.env = env; + this.exampleFilter = exampleFilter; + } + + @Override + public EssentialFilter[] filters() { + // Use the example filter if we're running development mode. If + // we're running in production or test mode then don't use any + // filters at all. + if (env.mode().equals(Mode.DEV)) { + return new EssentialFilter[] { exampleFilter }; + } else { + return new EssentialFilter[] {}; + } + } + +} diff --git a/play-framework/introduction/app/Module.java b/play-framework/introduction/app/Module.java new file mode 100644 index 0000000000..6e7d1766ef --- /dev/null +++ b/play-framework/introduction/app/Module.java @@ -0,0 +1,31 @@ +import com.google.inject.AbstractModule; +import java.time.Clock; + +import services.ApplicationTimer; +import services.AtomicCounter; +import services.Counter; + +/** + * This class is a Guice module that tells Guice how to bind several + * different types. This Guice module is created when the Play + * application starts. + * + * Play will automatically use any class called `Module` that is in + * the root package. You can create modules in other locations by + * adding `play.modules.enabled` settings to the `application.conf` + * configuration file. + */ +public class Module extends AbstractModule { + + @Override + public void configure() { + // Use the system clock as the default implementation of Clock + bind(Clock.class).toInstance(Clock.systemDefaultZone()); + // Ask Guice to create an instance of ApplicationTimer when the + // application starts. + bind(ApplicationTimer.class).asEagerSingleton(); + // Set AtomicCounter as the implementation for Counter. + bind(Counter.class).to(AtomicCounter.class); + } + +} diff --git a/play-framework/introduction/app/controllers/AsyncController.java b/play-framework/introduction/app/controllers/AsyncController.java new file mode 100644 index 0000000000..92c84bb755 --- /dev/null +++ b/play-framework/introduction/app/controllers/AsyncController.java @@ -0,0 +1,64 @@ +package controllers; + +import akka.actor.ActorSystem; + +import javax.inject.*; + +import play.*; +import play.mvc.*; + +import java.util.concurrent.Executor; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.TimeUnit; + +import scala.concurrent.duration.Duration; +import scala.concurrent.ExecutionContextExecutor; + +/** + * This controller contains an action that demonstrates how to write + * simple asynchronous code in a controller. It uses a timer to + * asynchronously delay sending a response for 1 second. + * + * @param actorSystem We need the {@link ActorSystem}'s + * {@link Scheduler} to run code after a delay. + * @param exec We need a Java {@link Executor} to apply the result + * of the {@link CompletableFuture} and a Scala + * {@link ExecutionContext} so we can use the Akka {@link Scheduler}. + * An {@link ExecutionContextExecutor} implements both interfaces. + */ +@Singleton +public class AsyncController extends Controller { + + private final ActorSystem actorSystem; + private final ExecutionContextExecutor exec; + + @Inject + public AsyncController(ActorSystem actorSystem, ExecutionContextExecutor exec) { + this.actorSystem = actorSystem; + this.exec = exec; + } + + /** + * An action that returns a plain text message after a delay + * of 1 second. + *

+ * The configuration in the routes file means that this method + * will be called when the application receives a GET request with + * a path of /message. + */ + public CompletionStage message() { + return getFutureMessage(1, TimeUnit.SECONDS).thenApplyAsync(Results::ok, exec); + } + + private CompletionStage getFutureMessage(long time, TimeUnit timeUnit) { + CompletableFuture future = new CompletableFuture<>(); + actorSystem.scheduler().scheduleOnce( + Duration.create(time, timeUnit), + () -> future.complete("Hi!"), + exec + ); + return future; + } + +} diff --git a/play-framework/introduction/app/controllers/CountController.java b/play-framework/introduction/app/controllers/CountController.java new file mode 100644 index 0000000000..02fcb15f8e --- /dev/null +++ b/play-framework/introduction/app/controllers/CountController.java @@ -0,0 +1,35 @@ +package controllers; + +import javax.inject.*; +import play.*; +import play.mvc.*; + +import services.Counter; + +/** + * This controller demonstrates how to use dependency injection to + * bind a component into a controller class. The class contains an + * action that shows an incrementing count to users. The {@link Counter} + * object is injected by the Guice dependency injection system. + */ +@Singleton +public class CountController extends Controller { + + private final Counter counter; + + @Inject + public CountController(Counter counter) { + this.counter = counter; + } + + /** + * An action that responds with the {@link Counter}'s current + * count. The result is plain text. This action is mapped to + * GET requests with a path of /count + * requests by an entry in the routes config file. + */ + public Result count() { + return ok(Integer.toString(counter.nextCount())); + } + +} diff --git a/play-framework/introduction/app/controllers/HomeController.java b/play-framework/introduction/app/controllers/HomeController.java new file mode 100644 index 0000000000..6a79856eb4 --- /dev/null +++ b/play-framework/introduction/app/controllers/HomeController.java @@ -0,0 +1,23 @@ +package controllers; + +import play.mvc.*; + +import views.html.*; + +/** + * This controller contains an action to handle HTTP requests + * to the application's home page. + */ +public class HomeController extends Controller { + + /** + * An action that renders an HTML page with a welcome message. + * The configuration in the routes file means that + * this method will be called when the application receives a + * GET request with a path of /. + */ + public Result index() { + return ok(index.render("Your new application is ready.")); + } + +} diff --git a/play-framework/introduction/app/controllers/StudentController.java b/play-framework/introduction/app/controllers/StudentController.java new file mode 100644 index 0000000000..8b759b9598 --- /dev/null +++ b/play-framework/introduction/app/controllers/StudentController.java @@ -0,0 +1,63 @@ +package controllers; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import models.Student; +import models.StudentStore; +import play.libs.Json; +import play.mvc.Controller; +import play.mvc.Result; +import util.Util; + +import java.util.Set; + +public class StudentController extends Controller { + public Result create() { + JsonNode json = request().body().asJson(); + if (json == null) { + return badRequest(Util.createResponse("Expecting Json data", false)); + } + Student student = StudentStore.getInstance().addStudent(Json.fromJson(json, Student.class)); + JsonNode jsonObject = Json.toJson(student); + return created(Util.createResponse(jsonObject, true)); + } + + public Result update() { + JsonNode json = request().body().asJson(); + if (json == null) { + return badRequest(Util.createResponse("Expecting Json data", false)); + } + Student student = StudentStore.getInstance().updateStudent(Json.fromJson(json, Student.class)); + if (student == null) { + return notFound(Util.createResponse("Student not found", false)); + } + + JsonNode jsonObject = Json.toJson(student); + return ok(Util.createResponse(jsonObject, true)); + } + + public Result retrieve(int id) { + if (StudentStore.getInstance().getStudent(id) == null) { + return notFound(Util.createResponse("Student with id:" + id + " not found", false)); + } + JsonNode jsonObjects = Json.toJson(StudentStore.getInstance().getStudent(id)); + return ok(Util.createResponse(jsonObjects, true)); + } + + public Result listStudents() { + Set result = StudentStore.getInstance().getAllStudents(); + ObjectMapper mapper = new ObjectMapper(); + + JsonNode jsonData = mapper.convertValue(result, JsonNode.class); + return ok(Util.createResponse(jsonData, true)); + + } + + public Result delete(int id) { + if (!StudentStore.getInstance().deleteStudent(id)) { + return notFound(Util.createResponse("Student with id:" + id + " not found", false)); + } + return ok(Util.createResponse("Student with id:" + id + " deleted", true)); + } + +} diff --git a/play-framework/introduction/app/filters/ExampleFilter.java b/play-framework/introduction/app/filters/ExampleFilter.java new file mode 100644 index 0000000000..67a6a36cc3 --- /dev/null +++ b/play-framework/introduction/app/filters/ExampleFilter.java @@ -0,0 +1,45 @@ +package filters; + +import akka.stream.Materializer; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Executor; +import java.util.function.Function; +import javax.inject.*; +import play.mvc.*; +import play.mvc.Http.RequestHeader; + + +/** + * This is a simple filter that adds a header to all requests. It's + * added to the application's list of filters by the + * {@link Filters} class. + */ +@Singleton +public class ExampleFilter extends Filter { + + private final Executor exec; + + /** + * @param mat This object is needed to handle streaming of requests + * and responses. + * @param exec This class is needed to execute code asynchronously. + * It is used below by the thenAsyncApply method. + */ + @Inject + public ExampleFilter(Materializer mat, Executor exec) { + super(mat); + this.exec = exec; + } + + @Override + public CompletionStage apply( + Function> next, + RequestHeader requestHeader) { + + return next.apply(requestHeader).thenApplyAsync( + result -> result.withHeader("X-ExampleFilter", "foo"), + exec + ); + } + +} diff --git a/play-framework/introduction/app/models/Student.java b/play-framework/introduction/app/models/Student.java new file mode 100644 index 0000000000..dc539767bd --- /dev/null +++ b/play-framework/introduction/app/models/Student.java @@ -0,0 +1,47 @@ +package models; +public class Student { + private String firstName; + private String lastName; + private int age; + private int id; + public Student(){} + public Student(String firstName, String lastName, int age) { + super(); + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + +} diff --git a/play-framework/introduction/app/models/StudentStore.java b/play-framework/introduction/app/models/StudentStore.java new file mode 100644 index 0000000000..add6a5dbd6 --- /dev/null +++ b/play-framework/introduction/app/models/StudentStore.java @@ -0,0 +1,46 @@ +package models; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class StudentStore { + private static StudentStore instance; + private Map students = new HashMap<>(); + + public static StudentStore getInstance() { + if (instance == null) { + instance = new StudentStore(); + } + return instance; + } + + public Student addStudent(Student student) { + int id = students.size(); + student.setId(id); + students.put(id, student); + return student; + } + + public Student getStudent(int id) { + return students.get(id); + } + + public Set getAllStudents() { + return new HashSet<>(students.values()); + } + + public Student updateStudent(Student student) { + int id = student.getId(); + if (students.containsKey(id)) { + students.put(id, student); + return student; + } + return null; + } + + public boolean deleteStudent(int id) { + return students.remove(id) != null; + } +} \ No newline at end of file diff --git a/play-framework/introduction/app/services/ApplicationTimer.java b/play-framework/introduction/app/services/ApplicationTimer.java new file mode 100644 index 0000000000..a951562b1d --- /dev/null +++ b/play-framework/introduction/app/services/ApplicationTimer.java @@ -0,0 +1,50 @@ +package services; + +import java.time.Clock; +import java.time.Instant; +import java.util.concurrent.CompletableFuture; +import javax.inject.*; +import play.Logger; +import play.inject.ApplicationLifecycle; + +/** + * This class demonstrates how to run code when the + * application starts and stops. It starts a timer when the + * application starts. When the application stops it prints out how + * long the application was running for. + * + * This class is registered for Guice dependency injection in the + * {@link Module} class. We want the class to start when the application + * starts, so it is registered as an "eager singleton". See the code + * in the {@link Module} class to see how this happens. + * + * This class needs to run code when the server stops. It uses the + * application's {@link ApplicationLifecycle} to register a stop hook. + */ +@Singleton +public class ApplicationTimer { + + private final Clock clock; + private final ApplicationLifecycle appLifecycle; + private final Instant start; + + @Inject + public ApplicationTimer(Clock clock, ApplicationLifecycle appLifecycle) { + this.clock = clock; + this.appLifecycle = appLifecycle; + // This code is called when the application starts. + start = clock.instant(); + Logger.info("ApplicationTimer demo: Starting application at " + start); + + // When the application starts, register a stop hook with the + // ApplicationLifecycle object. The code inside the stop hook will + // be run when the application stops. + appLifecycle.addStopHook(() -> { + Instant stop = clock.instant(); + Long runningTime = stop.getEpochSecond() - start.getEpochSecond(); + Logger.info("ApplicationTimer demo: Stopping application at " + clock.instant() + " after " + runningTime + "s."); + return CompletableFuture.completedFuture(null); + }); + } + +} diff --git a/play-framework/introduction/app/services/AtomicCounter.java b/play-framework/introduction/app/services/AtomicCounter.java new file mode 100644 index 0000000000..41f741cbf7 --- /dev/null +++ b/play-framework/introduction/app/services/AtomicCounter.java @@ -0,0 +1,26 @@ +package services; + +import java.util.concurrent.atomic.AtomicInteger; +import javax.inject.*; + +/** + * This class is a concrete implementation of the {@link Counter} trait. + * It is configured for Guice dependency injection in the {@link Module} + * class. + * + * This class has a {@link Singleton} annotation because we need to make + * sure we only use one counter per application. Without this + * annotation we would get a new instance every time a {@link Counter} is + * injected. + */ +@Singleton +public class AtomicCounter implements Counter { + + private final AtomicInteger atomicCounter = new AtomicInteger(); + + @Override + public int nextCount() { + return atomicCounter.getAndIncrement(); + } + +} diff --git a/play-framework/introduction/app/services/Counter.java b/play-framework/introduction/app/services/Counter.java new file mode 100644 index 0000000000..dadad8b09d --- /dev/null +++ b/play-framework/introduction/app/services/Counter.java @@ -0,0 +1,13 @@ +package services; + +/** + * This interface demonstrates how to create a component that is injected + * into a controller. The interface represents a counter that returns a + * incremented number each time it is called. + * + * The {@link Modules} class binds this interface to the + * {@link AtomicCounter} implementation. + */ +public interface Counter { + int nextCount(); +} diff --git a/play-framework/introduction/app/util/Util.java b/play-framework/introduction/app/util/Util.java new file mode 100644 index 0000000000..a853a4cb43 --- /dev/null +++ b/play-framework/introduction/app/util/Util.java @@ -0,0 +1,17 @@ +package util; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import play.libs.Json; + +public class Util { + public static ObjectNode createResponse(Object response, boolean ok) { + ObjectNode result = Json.newObject(); + result.put("isSuccessfull", ok); + if (response instanceof String) + result.put("body", (String) response); + else result.put("body", (JsonNode) response); + + return result; + } +} \ No newline at end of file diff --git a/play-framework/introduction/app/views/index.scala.html b/play-framework/introduction/app/views/index.scala.html new file mode 100644 index 0000000000..4539f5a10b --- /dev/null +++ b/play-framework/introduction/app/views/index.scala.html @@ -0,0 +1,20 @@ +@* + * This template takes a single argument, a String containing a + * message to display. + *@ +@(message: String) + +@* + * Call the `main` template with two arguments. The first + * argument is a `String` with the title of the page, the second + * argument is an `Html` object containing the body of the page. + *@ +@main("Welcome to Play") { + + @* + * Get an `Html` object by calling the built-in Play welcome + * template and passing a `String` message. + *@ + @play20.welcome(message, style = "Java") + +} diff --git a/play-framework/introduction/app/views/main.scala.html b/play-framework/introduction/app/views/main.scala.html new file mode 100644 index 0000000000..9414f4be6e --- /dev/null +++ b/play-framework/introduction/app/views/main.scala.html @@ -0,0 +1,23 @@ +@* + * This template is called from the `index` template. This template + * handles the rendering of the page header and body tags. It takes + * two arguments, a `String` for the title of the page and an `Html` + * object to insert into the body of the page. + *@ +@(title: String)(content: Html) + + + + + @* Here's where we render the page title `String`. *@ + @title + + + + + + @* And here's where we render the `Html` object containing + * the page content. *@ + @content + + diff --git a/play-framework/introduction/bin/activator b/play-framework/introduction/bin/activator new file mode 100644 index 0000000000..a8b11d482f --- /dev/null +++ b/play-framework/introduction/bin/activator @@ -0,0 +1,397 @@ +#!/usr/bin/env bash + +### ------------------------------- ### +### Helper methods for BASH scripts ### +### ------------------------------- ### + +realpath () { +( + TARGET_FILE="$1" + FIX_CYGPATH="$2" + + cd "$(dirname "$TARGET_FILE")" + TARGET_FILE=$(basename "$TARGET_FILE") + + COUNT=0 + while [ -L "$TARGET_FILE" -a $COUNT -lt 100 ] + do + TARGET_FILE=$(readlink "$TARGET_FILE") + cd "$(dirname "$TARGET_FILE")" + TARGET_FILE=$(basename "$TARGET_FILE") + COUNT=$(($COUNT + 1)) + done + + # make sure we grab the actual windows path, instead of cygwin's path. + if [[ "x$FIX_CYGPATH" != "x" ]]; then + echo "$(cygwinpath "$(pwd -P)/$TARGET_FILE")" + else + echo "$(pwd -P)/$TARGET_FILE" + fi +) +} + + +# Uses uname to detect if we're in the odd cygwin environment. +is_cygwin() { + local os=$(uname -s) + case "$os" in + CYGWIN*) return 0 ;; + *) return 1 ;; + esac +} + +# TODO - Use nicer bash-isms here. +CYGWIN_FLAG=$(if is_cygwin; then echo true; else echo false; fi) + + +# This can fix cygwin style /cygdrive paths so we get the +# windows style paths. +cygwinpath() { + local file="$1" + if [[ "$CYGWIN_FLAG" == "true" ]]; then + echo $(cygpath -w $file) + else + echo $file + fi +} + +# Make something URI friendly +make_url() { + url="$1" + local nospaces=${url// /%20} + if is_cygwin; then + echo "/${nospaces//\\//}" + else + echo "$nospaces" + fi +} + +declare -a residual_args +declare -a java_args +declare -a scalac_args +declare -a sbt_commands +declare java_cmd=java +declare java_version +declare -r real_script_path="$(realpath "$0")" +declare -r sbt_home="$(realpath "$(dirname "$(dirname "$real_script_path")")")" +declare -r sbt_bin_dir="$(dirname "$real_script_path")" +declare -r app_version="1.3.10" + +declare -r script_name=activator +declare -r java_opts=( "${ACTIVATOR_OPTS[@]}" "${SBT_OPTS[@]}" "${JAVA_OPTS[@]}" "${java_opts[@]}" ) +userhome="$HOME" +if is_cygwin; then + # cygwin sets home to something f-d up, set to real windows homedir + userhome="$USERPROFILE" +fi +declare -r activator_user_home_dir="${userhome}/.activator" +declare -r java_opts_config_home="${activator_user_home_dir}/activatorconfig.txt" +declare -r java_opts_config_version="${activator_user_home_dir}/${app_version}/activatorconfig.txt" + +echoerr () { + echo 1>&2 "$@" +} +vlog () { + [[ $verbose || $debug ]] && echoerr "$@" +} +dlog () { + [[ $debug ]] && echoerr "$@" +} + +jar_file () { + echo "$(cygwinpath "${sbt_home}/libexec/activator-launch-${app_version}.jar")" +} + +acquire_sbt_jar () { + sbt_jar="$(jar_file)" + + if [[ ! -f "$sbt_jar" ]]; then + echoerr "Could not find launcher jar: $sbt_jar" + exit 2 + fi +} + +execRunner () { + # print the arguments one to a line, quoting any containing spaces + [[ $verbose || $debug ]] && echo "# Executing command line:" && { + for arg; do + if printf "%s\n" "$arg" | grep -q ' '; then + printf "\"%s\"\n" "$arg" + else + printf "%s\n" "$arg" + fi + done + echo "" + } + + # THis used to be exec, but we loose the ability to re-hook stty then + # for cygwin... Maybe we should flag the feature here... + "$@" +} + +addJava () { + dlog "[addJava] arg = '$1'" + java_args=( "${java_args[@]}" "$1" ) +} +addSbt () { + dlog "[addSbt] arg = '$1'" + sbt_commands=( "${sbt_commands[@]}" "$1" ) +} +addResidual () { + dlog "[residual] arg = '$1'" + residual_args=( "${residual_args[@]}" "$1" ) +} +addDebugger () { + addJava "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$1" +} + +get_mem_opts () { + # if we detect any of these settings in ${JAVA_OPTS} we need to NOT output our settings. + # The reason is the Xms/Xmx, if they don't line up, cause errors. + if [[ "${JAVA_OPTS}" == *-Xmx* ]] || [[ "${JAVA_OPTS}" == *-Xms* ]] || [[ "${JAVA_OPTS}" == *-XX:MaxPermSize* ]] || [[ "${JAVA_OPTS}" == *-XX:MaxMetaspaceSize* ]] || [[ "${JAVA_OPTS}" == *-XX:ReservedCodeCacheSize* ]]; then + echo "" + else + # a ham-fisted attempt to move some memory settings in concert + # so they need not be messed around with individually. + local mem=${1:-1024} + local codecache=$(( $mem / 8 )) + (( $codecache > 128 )) || codecache=128 + (( $codecache < 512 )) || codecache=512 + local class_metadata_size=$(( $codecache * 2 )) + local class_metadata_opt=$([[ "$java_version" < "1.8" ]] && echo "MaxPermSize" || echo "MaxMetaspaceSize") + + echo "-Xms${mem}m -Xmx${mem}m -XX:ReservedCodeCacheSize=${codecache}m -XX:${class_metadata_opt}=${class_metadata_size}m" + fi +} + +require_arg () { + local type="$1" + local opt="$2" + local arg="$3" + if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then + echo "$opt requires <$type> argument" + exit 1 + fi +} + +is_function_defined() { + declare -f "$1" > /dev/null +} + +# If we're *not* running in a terminal, and we don't have any arguments, then we need to add the 'ui' parameter +detect_terminal_for_ui() { + [[ ! -t 0 ]] && [[ "${#residual_args}" == "0" ]] && { + addResidual "ui" + } + # SPECIAL TEST FOR MAC + [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]] && [[ "${#residual_args}" == "0" ]] && { + echo "Detected MAC OSX launched script...." + echo "Swapping to UI" + addResidual "ui" + } +} + +process_args () { + while [[ $# -gt 0 ]]; do + case "$1" in + -h|-help) usage; exit 1 ;; + -v|-verbose) verbose=1 && shift ;; + -d|-debug) debug=1 && shift ;; + + -ivy) require_arg path "$1" "$2" && addJava "-Dsbt.ivy.home=$2" && shift 2 ;; + -mem) require_arg integer "$1" "$2" && sbt_mem="$2" && shift 2 ;; + -jvm-debug) require_arg port "$1" "$2" && addDebugger $2 && shift 2 ;; + -batch) exec &1 | awk -F '"' '/version/ {print $2}') + vlog "[process_args] java_version = '$java_version'" +} + +# Detect that we have java installed. +checkJava() { + local required_version="$1" + # Now check to see if it's a good enough version + if [[ "$java_version" == "" ]]; then + echo + echo No java installations was detected. + echo Please go to http://www.java.com/getjava/ and download + echo + exit 1 + elif [[ ! "$java_version" > "$required_version" ]]; then + echo + echo The java installation you have is not up to date + echo $script_name requires at least version $required_version+, you have + echo version $java_version + echo + echo Please go to http://www.java.com/getjava/ and download + echo a valid Java Runtime and install before running $script_name. + echo + exit 1 + fi +} + + +run() { + # no jar? download it. + [[ -f "$sbt_jar" ]] || acquire_sbt_jar "$sbt_version" || { + # still no jar? uh-oh. + echo "Download failed. Obtain the sbt-launch.jar manually and place it at $sbt_jar" + exit 1 + } + + # process the combined args, then reset "$@" to the residuals + process_args "$@" + detect_terminal_for_ui + set -- "${residual_args[@]}" + argumentCount=$# + + # TODO - java check should be configurable... + checkJava "1.6" + + #If we're in cygwin, we should use the windows config, and terminal hacks + if [[ "$CYGWIN_FLAG" == "true" ]]; then + stty -icanon min 1 -echo > /dev/null 2>&1 + addJava "-Djline.terminal=jline.UnixTerminal" + addJava "-Dsbt.cygwin=true" + fi + + # run sbt + execRunner "$java_cmd" \ + "-Dactivator.home=$(make_url "$sbt_home")" \ + ${SBT_OPTS:-$default_sbt_opts} \ + $(get_mem_opts $sbt_mem) \ + ${JAVA_OPTS} \ + ${java_args[@]} \ + -jar "$sbt_jar" \ + "${sbt_commands[@]}" \ + "${residual_args[@]}" + + exit_code=$? + + # Clean up the terminal from cygwin hacks. + if [[ "$CYGWIN_FLAG" == "true" ]]; then + stty icanon echo > /dev/null 2>&1 + fi + exit $exit_code +} + + +declare -r noshare_opts="-Dsbt.global.base=project/.sbtboot -Dsbt.boot.directory=project/.boot -Dsbt.ivy.home=project/.ivy" +declare -r sbt_opts_file=".sbtopts" +declare -r etc_sbt_opts_file="${sbt_home}/conf/sbtopts" +declare -r win_sbt_opts_file="${sbt_home}/conf/sbtconfig.txt" + +usage() { + cat < path to global settings/plugins directory (default: ~/.sbt) + -sbt-boot path to shared boot directory (default: ~/.sbt/boot in 0.11 series) + -ivy path to local Ivy repository (default: ~/.ivy2) + -mem set memory options (default: $sbt_mem, which is $(get_mem_opts $sbt_mem)) + -no-share use all local caches; no sharing + -no-global uses global caches, but does not use global ~/.sbt directory. + -jvm-debug Turn on JVM debugging, open at the given port. + -batch Disable interactive mode + + # sbt version (default: from project/build.properties if present, else latest release) + -sbt-version use the specified version of sbt + -sbt-jar use the specified jar as the sbt launcher + -sbt-rc use an RC version of sbt + -sbt-snapshot use a snapshot version of sbt + + # java version (default: java from PATH, currently $(java -version 2>&1 | grep version)) + -java-home alternate JAVA_HOME + + # jvm options and output control + JAVA_OPTS environment variable, if unset uses "$java_opts" + SBT_OPTS environment variable, if unset uses "$default_sbt_opts" + ACTIVATOR_OPTS Environment variable, if unset uses "" + .sbtopts if this file exists in the current directory, it is + prepended to the runner args + /etc/sbt/sbtopts if this file exists, it is prepended to the runner args + -Dkey=val pass -Dkey=val directly to the java runtime + -J-X pass option -X directly to the java runtime + (-J is stripped) + -S-X add -X to sbt's scalacOptions (-S is stripped) + +In the case of duplicated or conflicting options, the order above +shows precedence: JAVA_OPTS lowest, command line options highest. +EOM +} + + + +process_my_args () { + while [[ $# -gt 0 ]]; do + case "$1" in + -no-colors) addJava "-Dsbt.log.noformat=true" && shift ;; + -no-share) addJava "$noshare_opts" && shift ;; + -no-global) addJava "-Dsbt.global.base=$(pwd)/project/.sbtboot" && shift ;; + -sbt-boot) require_arg path "$1" "$2" && addJava "-Dsbt.boot.directory=$2" && shift 2 ;; + -sbt-dir) require_arg path "$1" "$2" && addJava "-Dsbt.global.base=$2" && shift 2 ;; + -debug-inc) addJava "-Dxsbt.inc.debug=true" && shift ;; + -batch) exec ^&1') do ( + if %%~j==java set JAVAINSTALLED=1 + if %%~j==openjdk set JAVAINSTALLED=1 +) + +rem Detect the same thing about javac +if "%_JAVACCMD%"=="" ( + if not "%JAVA_HOME%"=="" ( + if exist "%JAVA_HOME%\bin\javac.exe" set "_JAVACCMD=%JAVA_HOME%\bin\javac.exe" + ) +) +if "%_JAVACCMD%"=="" set _JAVACCMD=javac +for /F %%j in ('"%_JAVACCMD%" -version 2^>^&1') do ( + if %%~j==javac set JAVACINSTALLED=1 +) + +rem BAT has no logical or, so we do it OLD SCHOOL! Oppan Redmond Style +set JAVAOK=true +if not defined JAVAINSTALLED set JAVAOK=false +if not defined JAVACINSTALLED set JAVAOK=false + +if "%JAVAOK%"=="false" ( + echo. + echo A Java JDK is not installed or can't be found. + if not "%JAVA_HOME%"=="" ( + echo JAVA_HOME = "%JAVA_HOME%" + ) + echo. + echo Please go to + echo http://www.oracle.com/technetwork/java/javase/downloads/index.html + echo and download a valid Java JDK and install before running Activator. + echo. + echo If you think this message is in error, please check + echo your environment variables to see if "java.exe" and "javac.exe" are + echo available via JAVA_HOME or PATH. + echo. + if defined DOUBLECLICKED pause + exit /B 1 +) + +rem Check what Java version is being used to determine what memory options to use +for /f "tokens=3" %%g in ('java -version 2^>^&1 ^| findstr /i "version"') do ( + set JAVA_VERSION=%%g +) + +rem Strips away the " characters +set JAVA_VERSION=%JAVA_VERSION:"=% + +rem TODO Check if there are existing mem settings in JAVA_OPTS/CFG_OPTS and use those instead of the below +for /f "delims=. tokens=1-3" %%v in ("%JAVA_VERSION%") do ( + set MAJOR=%%v + set MINOR=%%w + set BUILD=%%x + + set META_SIZE=-XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=256M + if "!MINOR!" LSS "8" ( + set META_SIZE=-XX:PermSize=64M -XX:MaxPermSize=256M + ) + + set MEM_OPTS=!META_SIZE! + ) + +rem We use the value of the JAVA_OPTS environment variable if defined, rather than the config. +set _JAVA_OPTS=%JAVA_OPTS% +if "%_JAVA_OPTS%"=="" set _JAVA_OPTS=%CFG_OPTS% + +set DEBUG_OPTS= + +rem Loop through the arguments, building remaining args in args variable +set args= +:argsloop +if not "%~1"=="" ( + rem Checks if the argument contains "-D" and if true, adds argument 1 with 2 and puts an equal sign between them. + rem This is done since batch considers "=" to be a delimiter so we need to circumvent this behavior with a small hack. + set arg1=%~1 + if "!arg1:~0,2!"=="-D" ( + set "args=%args% "%~1"="%~2"" + shift + shift + goto argsloop + ) + + if "%~1"=="-jvm-debug" ( + if not "%~2"=="" ( + rem This piece of magic somehow checks that an argument is a number + for /F "delims=0123456789" %%i in ("%~2") do ( + set var="%%i" + ) + if defined var ( + rem Not a number, assume no argument given and default to 9999 + set JPDA_PORT=9999 + ) else ( + rem Port was given, shift arguments + set JPDA_PORT=%~2 + shift + ) + ) else ( + set JPDA_PORT=9999 + ) + shift + + set DEBUG_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=!JPDA_PORT! + goto argsloop + ) + rem else + set "args=%args% "%~1"" + shift + goto argsloop +) + +:run + +if "!args!"=="" ( + if defined DOUBLECLICKED ( + set CMDS="ui" + ) else set CMDS=!args! +) else set CMDS=!args! + +rem We add a / in front, so we get file:///C: instead of file://C: +rem Java considers the later a UNC path. +rem We also attempt a solid effort at making it URI friendly. +rem We don't even bother with UNC paths. +set JAVA_FRIENDLY_HOME_1=/!ACTIVATOR_HOME:\=/! +set JAVA_FRIENDLY_HOME=/!JAVA_FRIENDLY_HOME_1: =%%20! + +rem Checks if the command contains spaces to know if it should be wrapped in quotes or not +set NON_SPACED_CMD=%_JAVACMD: =% +if "%_JAVACMD%"=="%NON_SPACED_CMD%" %_JAVACMD% %DEBUG_OPTS% %MEM_OPTS% %ACTIVATOR_OPTS% %SBT_OPTS% %_JAVA_OPTS% "-Dactivator.home=%JAVA_FRIENDLY_HOME%" -jar "%ACTIVATOR_HOME%\libexec\%ACTIVATOR_LAUNCH_JAR%" %CMDS% +if NOT "%_JAVACMD%"=="%NON_SPACED_CMD%" "%_JAVACMD%" %DEBUG_OPTS% %MEM_OPTS% %ACTIVATOR_OPTS% %SBT_OPTS% %_JAVA_OPTS% "-Dactivator.home=%JAVA_FRIENDLY_HOME%" -jar "%ACTIVATOR_HOME%\libexec\%ACTIVATOR_LAUNCH_JAR%" %CMDS% + +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end + +@endlocal + +exit /B %ERROR_CODE% diff --git a/play-framework/introduction/build.sbt b/play-framework/introduction/build.sbt new file mode 100644 index 0000000000..0f5ea736f6 --- /dev/null +++ b/play-framework/introduction/build.sbt @@ -0,0 +1,13 @@ +name := """student-api""" + +version := "1.0-SNAPSHOT" + +lazy val root = (project in file(".")).enablePlugins(PlayJava) + +scalaVersion := "2.11.7" + +libraryDependencies ++= Seq( + javaJdbc, + cache, + javaWs +) diff --git a/play-framework/introduction/conf/application.conf b/play-framework/introduction/conf/application.conf new file mode 100644 index 0000000000..489d3f9b3e --- /dev/null +++ b/play-framework/introduction/conf/application.conf @@ -0,0 +1,353 @@ +# This is the main configuration file for the application. +# https://www.playframework.com/documentation/latest/ConfigFile +# ~~~~~ +# Play uses HOCON as its configuration file format. HOCON has a number +# of advantages over other config formats, but there are two things that +# can be used when modifying settings. +# +# You can include other configuration files in this main application.conf file: +#include "extra-config.conf" +# +# You can declare variables and substitute for them: +#mykey = ${some.value} +# +# And if an environment variable exists when there is no other subsitution, then +# HOCON will fall back to substituting environment variable: +#mykey = ${JAVA_HOME} + +## Akka +# https://www.playframework.com/documentation/latest/ScalaAkka#Configuration +# https://www.playframework.com/documentation/latest/JavaAkka#Configuration +# ~~~~~ +# Play uses Akka internally and exposes Akka Streams and actors in Websockets and +# other streaming HTTP responses. +akka { + # "akka.log-config-on-start" is extraordinarly useful because it log the complete + # configuration at INFO level, including defaults and overrides, so it s worth + # putting at the very top. + # + # Put the following in your conf/logback.xml file: + # + # + # + # And then uncomment this line to debug the configuration. + # + #log-config-on-start = true +} + +## Secret key +# http://www.playframework.com/documentation/latest/ApplicationSecret +# ~~~~~ +# The secret key is used to sign Play's session cookie. +# This must be changed for production, but we don't recommend you change it in this file. +play.crypto.secret = "changeme" + +## Modules +# https://www.playframework.com/documentation/latest/Modules +# ~~~~~ +# Control which modules are loaded when Play starts. Note that modules are +# the replacement for "GlobalSettings", which are deprecated in 2.5.x. +# Please see https://www.playframework.com/documentation/latest/GlobalSettings +# for more information. +# +# You can also extend Play functionality by using one of the publically available +# Play modules: https://playframework.com/documentation/latest/ModuleDirectory +play.modules { + # By default, Play will load any class called Module that is defined + # in the root package (the "app" directory), or you can define them + # explicitly below. + # If there are any built-in modules that you want to disable, you can list them here. + #enabled += my.application.Module + + # If there are any built-in modules that you want to disable, you can list them here. + #disabled += "" +} + +## IDE +# https://www.playframework.com/documentation/latest/IDE +# ~~~~~ +# Depending on your IDE, you can add a hyperlink for errors that will jump you +# directly to the code location in the IDE in dev mode. The following line makes +# use of the IntelliJ IDEA REST interface: +#play.editor="http://localhost:63342/api/file/?file=%s&line=%s" + +## Internationalisation +# https://www.playframework.com/documentation/latest/JavaI18N +# https://www.playframework.com/documentation/latest/ScalaI18N +# ~~~~~ +# Play comes with its own i18n settings, which allow the user's preferred language +# to map through to internal messages, or allow the language to be stored in a cookie. +play.i18n { + # The application languages + langs = [ "en" ] + + # Whether the language cookie should be secure or not + #langCookieSecure = true + + # Whether the HTTP only attribute of the cookie should be set to true + #langCookieHttpOnly = true +} + +## Play HTTP settings +# ~~~~~ +play.http { + ## Router + # https://www.playframework.com/documentation/latest/JavaRouting + # https://www.playframework.com/documentation/latest/ScalaRouting + # ~~~~~ + # Define the Router object to use for this application. + # This router will be looked up first when the application is starting up, + # so make sure this is the entry point. + # Furthermore, it's assumed your route file is named properly. + # So for an application router like `my.application.Router`, + # you may need to define a router file `conf/my.application.routes`. + # Default to Routes in the root package (aka "apps" folder) (and conf/routes) + #router = my.application.Router + + ## Action Creator + # https://www.playframework.com/documentation/latest/JavaActionCreator + # ~~~~~ + #actionCreator = null + + ## ErrorHandler + # https://www.playframework.com/documentation/latest/JavaRouting + # https://www.playframework.com/documentation/latest/ScalaRouting + # ~~~~~ + # If null, will attempt to load a class called ErrorHandler in the root package, + #errorHandler = null + + ## Filters + # https://www.playframework.com/documentation/latest/ScalaHttpFilters + # https://www.playframework.com/documentation/latest/JavaHttpFilters + # ~~~~~ + # Filters run code on every request. They can be used to perform + # common logic for all your actions, e.g. adding common headers. + # Defaults to "Filters" in the root package (aka "apps" folder) + # Alternatively you can explicitly register a class here. + #filters = my.application.Filters + + ## Session & Flash + # https://www.playframework.com/documentation/latest/JavaSessionFlash + # https://www.playframework.com/documentation/latest/ScalaSessionFlash + # ~~~~~ + session { + # Sets the cookie to be sent only over HTTPS. + #secure = true + + # Sets the cookie to be accessed only by the server. + #httpOnly = true + + # Sets the max-age field of the cookie to 5 minutes. + # NOTE: this only sets when the browser will discard the cookie. Play will consider any + # cookie value with a valid signature to be a valid session forever. To implement a server side session timeout, + # you need to put a timestamp in the session and check it at regular intervals to possibly expire it. + #maxAge = 300 + + # Sets the domain on the session cookie. + #domain = "example.com" + } + + flash { + # Sets the cookie to be sent only over HTTPS. + #secure = true + + # Sets the cookie to be accessed only by the server. + #httpOnly = true + } +} + +## Netty Provider +# https://www.playframework.com/documentation/latest/SettingsNetty +# ~~~~~ +play.server.netty { + # Whether the Netty wire should be logged + #log.wire = true + + # If you run Play on Linux, you can use Netty's native socket transport + # for higher performance with less garbage. + #transport = "native" +} + +## WS (HTTP Client) +# https://www.playframework.com/documentation/latest/ScalaWS#Configuring-WS +# ~~~~~ +# The HTTP client primarily used for REST APIs. The default client can be +# configured directly, but you can also create different client instances +# with customized settings. You must enable this by adding to build.sbt: +# +# libraryDependencies += ws // or javaWs if using java +# +play.ws { + # Sets HTTP requests not to follow 302 requests + #followRedirects = false + + # Sets the maximum number of open HTTP connections for the client. + #ahc.maxConnectionsTotal = 50 + + ## WS SSL + # https://www.playframework.com/documentation/latest/WsSSL + # ~~~~~ + ssl { + # Configuring HTTPS with Play WS does not require programming. You can + # set up both trustManager and keyManager for mutual authentication, and + # turn on JSSE debugging in development with a reload. + #debug.handshake = true + #trustManager = { + # stores = [ + # { type = "JKS", path = "exampletrust.jks" } + # ] + #} + } +} + +## Cache +# https://www.playframework.com/documentation/latest/JavaCache +# https://www.playframework.com/documentation/latest/ScalaCache +# ~~~~~ +# Play comes with an integrated cache API that can reduce the operational +# overhead of repeated requests. You must enable this by adding to build.sbt: +# +# libraryDependencies += cache +# +play.cache { + # If you want to bind several caches, you can bind the individually + #bindCaches = ["db-cache", "user-cache", "session-cache"] +} + +## Filters +# https://www.playframework.com/documentation/latest/Filters +# ~~~~~ +# There are a number of built-in filters that can be enabled and configured +# to give Play greater security. You must enable this by adding to build.sbt: +# +# libraryDependencies += filters +# +play.filters { + ## CORS filter configuration + # https://www.playframework.com/documentation/latest/CorsFilter + # ~~~~~ + # CORS is a protocol that allows web applications to make requests from the browser + # across different domains. + # NOTE: You MUST apply the CORS configuration before the CSRF filter, as CSRF has + # dependencies on CORS settings. + cors { + # Filter paths by a whitelist of path prefixes + #pathPrefixes = ["/some/path", ...] + + # The allowed origins. If null, all origins are allowed. + #allowedOrigins = ["http://www.example.com"] + + # The allowed HTTP methods. If null, all methods are allowed + #allowedHttpMethods = ["GET", "POST"] + } + + ## CSRF Filter + # https://www.playframework.com/documentation/latest/ScalaCsrf#Applying-a-global-CSRF-filter + # https://www.playframework.com/documentation/latest/JavaCsrf#Applying-a-global-CSRF-filter + # ~~~~~ + # Play supports multiple methods for verifying that a request is not a CSRF request. + # The primary mechanism is a CSRF token. This token gets placed either in the query string + # or body of every form submitted, and also gets placed in the users session. + # Play then verifies that both tokens are present and match. + csrf { + # Sets the cookie to be sent only over HTTPS + #cookie.secure = true + + # Defaults to CSRFErrorHandler in the root package. + #errorHandler = MyCSRFErrorHandler + } + + ## Security headers filter configuration + # https://www.playframework.com/documentation/latest/SecurityHeaders + # ~~~~~ + # Defines security headers that prevent XSS attacks. + # If enabled, then all options are set to the below configuration by default: + headers { + # The X-Frame-Options header. If null, the header is not set. + #frameOptions = "DENY" + + # The X-XSS-Protection header. If null, the header is not set. + #xssProtection = "1; mode=block" + + # The X-Content-Type-Options header. If null, the header is not set. + #contentTypeOptions = "nosniff" + + # The X-Permitted-Cross-Domain-Policies header. If null, the header is not set. + #permittedCrossDomainPolicies = "master-only" + + # The Content-Security-Policy header. If null, the header is not set. + #contentSecurityPolicy = "default-src 'self'" + } + + ## Allowed hosts filter configuration + # https://www.playframework.com/documentation/latest/AllowedHostsFilter + # ~~~~~ + # Play provides a filter that lets you configure which hosts can access your application. + # This is useful to prevent cache poisoning attacks. + hosts { + # Allow requests to example.com, its subdomains, and localhost:9000. + #allowed = [".example.com", "localhost:9000"] + } +} + +## Evolutions +# https://www.playframework.com/documentation/latest/Evolutions +# ~~~~~ +# Evolutions allows database scripts to be automatically run on startup in dev mode +# for database migrations. You must enable this by adding to build.sbt: +# +# libraryDependencies += evolutions +# +play.evolutions { + # You can disable evolutions for a specific datasource if necessary + #db.default.enabled = false +} + +## Database Connection Pool +# https://www.playframework.com/documentation/latest/SettingsJDBC +# ~~~~~ +# Play doesn't require a JDBC database to run, but you can easily enable one. +# +# libraryDependencies += jdbc +# +play.db { + # The combination of these two settings results in "db.default" as the + # default JDBC pool: + #config = "db" + #default = "default" + + # Play uses HikariCP as the default connection pool. You can override + # settings by changing the prototype: + prototype { + # Sets a fixed JDBC connection pool size of 50 + #hikaricp.minimumIdle = 50 + #hikaricp.maximumPoolSize = 50 + } +} + +## JDBC Datasource +# https://www.playframework.com/documentation/latest/JavaDatabase +# https://www.playframework.com/documentation/latest/ScalaDatabase +# ~~~~~ +# Once JDBC datasource is set up, you can work with several different +# database options: +# +# Slick (Scala preferred option): https://www.playframework.com/documentation/latest/PlaySlick +# JPA (Java preferred option): https://playframework.com/documentation/latest/JavaJPA +# EBean: https://playframework.com/documentation/latest/JavaEbean +# Anorm: https://www.playframework.com/documentation/latest/ScalaAnorm +# +db { + # You can declare as many datasources as you want. + # By convention, the default datasource is named `default` + + # https://www.playframework.com/documentation/latest/Developing-with-the-H2-Database + #default.driver = org.h2.Driver + #default.url = "jdbc:h2:mem:play" + #default.username = sa + #default.password = "" + + # You can turn on SQL logging for any datasource + # https://www.playframework.com/documentation/latest/Highlights25#Logging-SQL-statements + #default.logSql=true +} diff --git a/play-framework/introduction/conf/logback.xml b/play-framework/introduction/conf/logback.xml new file mode 100644 index 0000000000..86ec12c0af --- /dev/null +++ b/play-framework/introduction/conf/logback.xml @@ -0,0 +1,41 @@ + + + + + + + ${application.home:-.}/logs/application.log + + %date [%level] from %logger in %thread - %message%n%xException + + + + + + %coloredLevel %logger{15} - %message%n%xException{10} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/play-framework/introduction/conf/routes b/play-framework/introduction/conf/routes new file mode 100644 index 0000000000..ab55792683 --- /dev/null +++ b/play-framework/introduction/conf/routes @@ -0,0 +1,12 @@ +# Routes +# This file defines all application routes (Higher priority routes first) +# ~~~~ + +GET / controllers.StudentController.listStudents() +POST /:id controllers.StudentController.retrieve(id:Int) +POST / controllers.StudentController.create() +PUT / controllers.StudentController.update() +DELETE /:id controllers.StudentController.delete(id:Int) + +# Map static resources from the /public folder to the /assets URL path +GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset) diff --git a/play-framework/introduction/libexec/activator-launch-1.3.10.jar b/play-framework/introduction/libexec/activator-launch-1.3.10.jar new file mode 100644 index 0000000000..69050e7dec Binary files /dev/null and b/play-framework/introduction/libexec/activator-launch-1.3.10.jar differ diff --git a/play-framework/introduction/project/build.properties b/play-framework/introduction/project/build.properties new file mode 100644 index 0000000000..6d9fa6badb --- /dev/null +++ b/play-framework/introduction/project/build.properties @@ -0,0 +1,4 @@ +#Activator-generated Properties +#Wed Sep 07 12:29:40 EAT 2016 +template.uuid=c373963b-f5ad-433b-8e74-178e7ae25b1c +sbt.version=0.13.11 diff --git a/play-framework/introduction/project/plugins.sbt b/play-framework/introduction/project/plugins.sbt new file mode 100644 index 0000000000..51c5b2a35a --- /dev/null +++ b/play-framework/introduction/project/plugins.sbt @@ -0,0 +1,21 @@ +// The Play plugin +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.6") + +// Web plugins +addSbtPlugin("com.typesafe.sbt" % "sbt-coffeescript" % "1.0.0") +addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.1.0") +addSbtPlugin("com.typesafe.sbt" % "sbt-jshint" % "1.0.3") +addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.7") +addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.1.0") +addSbtPlugin("com.typesafe.sbt" % "sbt-mocha" % "1.1.0") +addSbtPlugin("org.irundaia.sbt" % "sbt-sassify" % "1.4.2") + +// Play enhancer - this automatically generates getters/setters for public fields +// and rewrites accessors of these fields to use the getters/setters. Remove this +// plugin if you prefer not to have this feature, or disable on a per project +// basis using disablePlugins(PlayEnhancer) in your build.sbt +addSbtPlugin("com.typesafe.sbt" % "sbt-play-enhancer" % "1.1.0") + +// Play Ebean support, to enable, uncomment this line, and enable in your build.sbt using +// enablePlugins(PlayEbean). +// addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "1.0.0") diff --git a/play-framework/introduction/public/images/favicon.png b/play-framework/introduction/public/images/favicon.png new file mode 100644 index 0000000000..c7d92d2ae4 Binary files /dev/null and b/play-framework/introduction/public/images/favicon.png differ diff --git a/play-framework/introduction/public/javascripts/hello.js b/play-framework/introduction/public/javascripts/hello.js new file mode 100644 index 0000000000..02ee13c7ca --- /dev/null +++ b/play-framework/introduction/public/javascripts/hello.js @@ -0,0 +1,3 @@ +if (window.console) { + console.log("Welcome to your Play application's JavaScript!"); +} diff --git a/play-framework/introduction/public/stylesheets/main.css b/play-framework/introduction/public/stylesheets/main.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/play-framework/introduction/test/ApplicationTest.java b/play-framework/introduction/test/ApplicationTest.java new file mode 100644 index 0000000000..1133978e9a --- /dev/null +++ b/play-framework/introduction/test/ApplicationTest.java @@ -0,0 +1,172 @@ + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Arrays; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Test; +import model.Student; +import play.test.*; +import static play.test.Helpers.*; + +public class ApplicationTest{ + private static final String BASE_URL = "http://localhost:9000"; + + @Test +public void testInServer() throws Exception { + TestServer server = testServer(3333); + running(server, () -> { + try { + WSClient ws = play.libs.ws.WS.newClient(3333); + CompletionStage completionStage = ws.url("/").get(); + WSResponse response = completionStage.toCompletableFuture().get(); + ws.close(); + assertEquals(OK, response.getStatus()); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + }); +} + @Test + public void whenCreatesRecord_thenCorrect() { + Student student = new Student("jody", "west", 50); + JSONObject obj = new JSONObject(makeRequest(BASE_URL, "POST", new JSONObject(student))); + assertTrue(obj.getBoolean("isSuccessfull")); + JSONObject body = obj.getJSONObject("body"); + assertEquals(student.getAge(), body.getInt("age")); + assertEquals(student.getFirstName(), body.getString("firstName")); + assertEquals(student.getLastName(), body.getString("lastName")); + } + + @Test + public void whenDeletesCreatedRecord_thenCorrect() { + Student student = new Student("Usain", "Bolt", 25); + JSONObject ob1 = new JSONObject(makeRequest(BASE_URL, "POST", new JSONObject(student))).getJSONObject("body"); + int id = ob1.getInt("id"); + JSONObject obj1 = new JSONObject(makeRequest(BASE_URL + "/" + id, "POST", new JSONObject())); + assertTrue(obj1.getBoolean("isSuccessfull")); + makeRequest(BASE_URL + "/" + id, "DELETE", null); + JSONObject obj2 = new JSONObject(makeRequest(BASE_URL + "/" + id, "POST", new JSONObject())); + assertFalse(obj2.getBoolean("isSuccessfull")); + } + + @Test + public void whenUpdatesCreatedRecord_thenCorrect() { + Student student = new Student("john", "doe", 50); + JSONObject body1 = new JSONObject(makeRequest(BASE_URL, "POST", new JSONObject(student))).getJSONObject("body"); + assertEquals(student.getAge(), body1.getInt("age")); + int newAge = 60; + body1.put("age", newAge); + JSONObject body2 = new JSONObject(makeRequest(BASE_URL, "PUT", body1)).getJSONObject("body"); + assertFalse(student.getAge() == body2.getInt("age")); + assertTrue(newAge == body2.getInt("age")); + } + + @Test + public void whenGetsAllRecords_thenCorrect() { + Student student1 = new Student("jane", "daisy", 50); + Student student2 = new Student("john", "daniel", 60); + Student student3 = new Student("don", "mason", 55); + Student student4 = new Student("scarlet", "ohara", 90); + + makeRequest(BASE_URL, "POST", new JSONObject(student1)); + makeRequest(BASE_URL, "POST", new JSONObject(student2)); + makeRequest(BASE_URL, "POST", new JSONObject(student3)); + makeRequest(BASE_URL, "POST", new JSONObject(student4)); + + JSONObject objects = new JSONObject(makeRequest(BASE_URL, "GET", null)); + assertTrue(objects.getBoolean("isSuccessfull")); + JSONArray array = objects.getJSONArray("body"); + assertTrue(array.length() >= 4); + } + + public static String makeRequest(String myUrl, String httpMethod, JSONObject parameters) { + + URL url = null; + try { + url = new URL(myUrl); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + HttpURLConnection conn = null; + try { + + conn = (HttpURLConnection) url.openConnection(); + } catch (IOException e) { + e.printStackTrace(); + } + conn.setDoInput(true); + + conn.setReadTimeout(10000); + + conn.setRequestProperty("Content-Type", "application/json"); + DataOutputStream dos = null; + int respCode = 0; + String inputString = null; + try { + conn.setRequestMethod(httpMethod); + + if (Arrays.asList("POST", "PUT").contains(httpMethod)) { + String params = parameters.toString(); + + conn.setDoOutput(true); + + dos = new DataOutputStream(conn.getOutputStream()); + dos.writeBytes(params); + dos.flush(); + dos.close(); + } + respCode = conn.getResponseCode(); + if (respCode != 200 && respCode != 201) { + String error = inputStreamToString(conn.getErrorStream()); + return error; + } + inputString = inputStreamToString(conn.getInputStream()); + + } catch (IOException e) { + + e.printStackTrace(); + } + return inputString; + } + + public static String inputStreamToString(InputStream is) { + BufferedReader br = null; + StringBuilder sb = new StringBuilder(); + + String line; + try { + + br = new BufferedReader(new InputStreamReader(is)); + while ((line = br.readLine()) != null) { + sb.append(line); + } + + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + return sb.toString(); + + } +} diff --git a/play-framework/routing-in-play/.gitignore b/play-framework/routing-in-play/.gitignore new file mode 100644 index 0000000000..eb372fc719 --- /dev/null +++ b/play-framework/routing-in-play/.gitignore @@ -0,0 +1,8 @@ +logs +target +/.idea +/.idea_modules +/.classpath +/.project +/.settings +/RUNNING_PID diff --git a/play-framework/routing-in-play/LICENSE b/play-framework/routing-in-play/LICENSE new file mode 100644 index 0000000000..4baedcb95f --- /dev/null +++ b/play-framework/routing-in-play/LICENSE @@ -0,0 +1,8 @@ +This software is licensed under the Apache 2 license, quoted below. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with +the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific +language governing permissions and limitations under the License. \ No newline at end of file diff --git a/play-framework/routing-in-play/README b/play-framework/routing-in-play/README new file mode 100644 index 0000000000..f21d092edf --- /dev/null +++ b/play-framework/routing-in-play/README @@ -0,0 +1,49 @@ +This is your new Play application +================================= + +This file will be packaged with your application when using `activator dist`. + +There are several demonstration files available in this template. + +Controllers +=========== + +- HomeController.java: + + Shows how to handle simple HTTP requests. + +- AsyncController.java: + + Shows how to do asynchronous programming when handling a request. + +- CountController.java: + + Shows how to inject a component into a controller and use the component when + handling requests. + +Components +========== + +- Module.java: + + Shows how to use Guice to bind all the components needed by your application. + +- Counter.java: + + An example of a component that contains state, in this case a simple counter. + +- ApplicationTimer.java: + + An example of a component that starts when the application starts and stops + when the application stops. + +Filters +======= + +- Filters.java: + + Creates the list of HTTP filters used by your application. + +- ExampleFilter.java + + A simple filter that adds a header to every response. \ No newline at end of file diff --git a/play-framework/routing-in-play/app/Filters.java b/play-framework/routing-in-play/app/Filters.java new file mode 100644 index 0000000000..255de8ca93 --- /dev/null +++ b/play-framework/routing-in-play/app/Filters.java @@ -0,0 +1,46 @@ +import javax.inject.*; +import play.*; +import play.mvc.EssentialFilter; +import play.http.HttpFilters; +import play.mvc.*; + +import filters.ExampleFilter; + +/** + * This class configures filters that run on every request. This + * class is queried by Play to get a list of filters. + * + * Play will automatically use filters from any class called + * Filters that is placed the root package. You can load filters + * from a different class by adding a `play.http.filters` setting to + * the application.conf configuration file. + */ +@Singleton +public class Filters implements HttpFilters { + + private final Environment env; + private final EssentialFilter exampleFilter; + + /** + * @param env Basic environment settings for the current application. + * @param exampleFilter A demonstration filter that adds a header to + */ + @Inject + public Filters(Environment env, ExampleFilter exampleFilter) { + this.env = env; + this.exampleFilter = exampleFilter; + } + + @Override + public EssentialFilter[] filters() { + // Use the example filter if we're running development mode. If + // we're running in production or test mode then don't use any + // filters at all. + if (env.mode().equals(Mode.DEV)) { + return new EssentialFilter[] { exampleFilter }; + } else { + return new EssentialFilter[] {}; + } + } + +} diff --git a/play-framework/routing-in-play/app/Module.java b/play-framework/routing-in-play/app/Module.java new file mode 100644 index 0000000000..6e7d1766ef --- /dev/null +++ b/play-framework/routing-in-play/app/Module.java @@ -0,0 +1,31 @@ +import com.google.inject.AbstractModule; +import java.time.Clock; + +import services.ApplicationTimer; +import services.AtomicCounter; +import services.Counter; + +/** + * This class is a Guice module that tells Guice how to bind several + * different types. This Guice module is created when the Play + * application starts. + * + * Play will automatically use any class called `Module` that is in + * the root package. You can create modules in other locations by + * adding `play.modules.enabled` settings to the `application.conf` + * configuration file. + */ +public class Module extends AbstractModule { + + @Override + public void configure() { + // Use the system clock as the default implementation of Clock + bind(Clock.class).toInstance(Clock.systemDefaultZone()); + // Ask Guice to create an instance of ApplicationTimer when the + // application starts. + bind(ApplicationTimer.class).asEagerSingleton(); + // Set AtomicCounter as the implementation for Counter. + bind(Counter.class).to(AtomicCounter.class); + } + +} diff --git a/play-framework/routing-in-play/app/controllers/HomeController.java b/play-framework/routing-in-play/app/controllers/HomeController.java new file mode 100644 index 0000000000..6e340d594f --- /dev/null +++ b/play-framework/routing-in-play/app/controllers/HomeController.java @@ -0,0 +1,33 @@ +package controllers; + +import play.mvc.*; + +import views.html.*; + +/** + * This controller contains an action to handle HTTP requests + * to the application's home page. + */ +public class HomeController extends Controller { + + /** + * An action that renders an HTML page with a welcome message. + * The configuration in the routes file means that + * this method will be called when the application receives a + * GET request with a path of /. + */ + public Result index(String author,int id) { + return ok("Routing in Play by:"+author+" ID:"+id); + } + public Result greet(String name,int age) { + return ok("Hello "+name+", you are "+age+" years old"); + } + public Result introduceMe(String data) { + String[] clientData=data.split(","); + return ok("Your name is "+clientData[0]+", you are "+clientData[1]+" years old"); + } + public Result squareMe(Long num) { + return ok(num+" Squared is "+(num*num)); + } + +} diff --git a/play-framework/routing-in-play/app/filters/ExampleFilter.java b/play-framework/routing-in-play/app/filters/ExampleFilter.java new file mode 100644 index 0000000000..67a6a36cc3 --- /dev/null +++ b/play-framework/routing-in-play/app/filters/ExampleFilter.java @@ -0,0 +1,45 @@ +package filters; + +import akka.stream.Materializer; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Executor; +import java.util.function.Function; +import javax.inject.*; +import play.mvc.*; +import play.mvc.Http.RequestHeader; + + +/** + * This is a simple filter that adds a header to all requests. It's + * added to the application's list of filters by the + * {@link Filters} class. + */ +@Singleton +public class ExampleFilter extends Filter { + + private final Executor exec; + + /** + * @param mat This object is needed to handle streaming of requests + * and responses. + * @param exec This class is needed to execute code asynchronously. + * It is used below by the thenAsyncApply method. + */ + @Inject + public ExampleFilter(Materializer mat, Executor exec) { + super(mat); + this.exec = exec; + } + + @Override + public CompletionStage apply( + Function> next, + RequestHeader requestHeader) { + + return next.apply(requestHeader).thenApplyAsync( + result -> result.withHeader("X-ExampleFilter", "foo"), + exec + ); + } + +} diff --git a/play-framework/routing-in-play/app/services/ApplicationTimer.java b/play-framework/routing-in-play/app/services/ApplicationTimer.java new file mode 100644 index 0000000000..a951562b1d --- /dev/null +++ b/play-framework/routing-in-play/app/services/ApplicationTimer.java @@ -0,0 +1,50 @@ +package services; + +import java.time.Clock; +import java.time.Instant; +import java.util.concurrent.CompletableFuture; +import javax.inject.*; +import play.Logger; +import play.inject.ApplicationLifecycle; + +/** + * This class demonstrates how to run code when the + * application starts and stops. It starts a timer when the + * application starts. When the application stops it prints out how + * long the application was running for. + * + * This class is registered for Guice dependency injection in the + * {@link Module} class. We want the class to start when the application + * starts, so it is registered as an "eager singleton". See the code + * in the {@link Module} class to see how this happens. + * + * This class needs to run code when the server stops. It uses the + * application's {@link ApplicationLifecycle} to register a stop hook. + */ +@Singleton +public class ApplicationTimer { + + private final Clock clock; + private final ApplicationLifecycle appLifecycle; + private final Instant start; + + @Inject + public ApplicationTimer(Clock clock, ApplicationLifecycle appLifecycle) { + this.clock = clock; + this.appLifecycle = appLifecycle; + // This code is called when the application starts. + start = clock.instant(); + Logger.info("ApplicationTimer demo: Starting application at " + start); + + // When the application starts, register a stop hook with the + // ApplicationLifecycle object. The code inside the stop hook will + // be run when the application stops. + appLifecycle.addStopHook(() -> { + Instant stop = clock.instant(); + Long runningTime = stop.getEpochSecond() - start.getEpochSecond(); + Logger.info("ApplicationTimer demo: Stopping application at " + clock.instant() + " after " + runningTime + "s."); + return CompletableFuture.completedFuture(null); + }); + } + +} diff --git a/play-framework/routing-in-play/app/services/AtomicCounter.java b/play-framework/routing-in-play/app/services/AtomicCounter.java new file mode 100644 index 0000000000..41f741cbf7 --- /dev/null +++ b/play-framework/routing-in-play/app/services/AtomicCounter.java @@ -0,0 +1,26 @@ +package services; + +import java.util.concurrent.atomic.AtomicInteger; +import javax.inject.*; + +/** + * This class is a concrete implementation of the {@link Counter} trait. + * It is configured for Guice dependency injection in the {@link Module} + * class. + * + * This class has a {@link Singleton} annotation because we need to make + * sure we only use one counter per application. Without this + * annotation we would get a new instance every time a {@link Counter} is + * injected. + */ +@Singleton +public class AtomicCounter implements Counter { + + private final AtomicInteger atomicCounter = new AtomicInteger(); + + @Override + public int nextCount() { + return atomicCounter.getAndIncrement(); + } + +} diff --git a/play-framework/routing-in-play/app/services/Counter.java b/play-framework/routing-in-play/app/services/Counter.java new file mode 100644 index 0000000000..dadad8b09d --- /dev/null +++ b/play-framework/routing-in-play/app/services/Counter.java @@ -0,0 +1,13 @@ +package services; + +/** + * This interface demonstrates how to create a component that is injected + * into a controller. The interface represents a counter that returns a + * incremented number each time it is called. + * + * The {@link Modules} class binds this interface to the + * {@link AtomicCounter} implementation. + */ +public interface Counter { + int nextCount(); +} diff --git a/play-framework/routing-in-play/app/views/index.scala.html b/play-framework/routing-in-play/app/views/index.scala.html new file mode 100644 index 0000000000..4539f5a10b --- /dev/null +++ b/play-framework/routing-in-play/app/views/index.scala.html @@ -0,0 +1,20 @@ +@* + * This template takes a single argument, a String containing a + * message to display. + *@ +@(message: String) + +@* + * Call the `main` template with two arguments. The first + * argument is a `String` with the title of the page, the second + * argument is an `Html` object containing the body of the page. + *@ +@main("Welcome to Play") { + + @* + * Get an `Html` object by calling the built-in Play welcome + * template and passing a `String` message. + *@ + @play20.welcome(message, style = "Java") + +} diff --git a/play-framework/routing-in-play/app/views/main.scala.html b/play-framework/routing-in-play/app/views/main.scala.html new file mode 100644 index 0000000000..9414f4be6e --- /dev/null +++ b/play-framework/routing-in-play/app/views/main.scala.html @@ -0,0 +1,23 @@ +@* + * This template is called from the `index` template. This template + * handles the rendering of the page header and body tags. It takes + * two arguments, a `String` for the title of the page and an `Html` + * object to insert into the body of the page. + *@ +@(title: String)(content: Html) + + + + + @* Here's where we render the page title `String`. *@ + @title + + + + + + @* And here's where we render the `Html` object containing + * the page content. *@ + @content + + diff --git a/play-framework/routing-in-play/bin/activator b/play-framework/routing-in-play/bin/activator new file mode 100644 index 0000000000..a8b11d482f --- /dev/null +++ b/play-framework/routing-in-play/bin/activator @@ -0,0 +1,397 @@ +#!/usr/bin/env bash + +### ------------------------------- ### +### Helper methods for BASH scripts ### +### ------------------------------- ### + +realpath () { +( + TARGET_FILE="$1" + FIX_CYGPATH="$2" + + cd "$(dirname "$TARGET_FILE")" + TARGET_FILE=$(basename "$TARGET_FILE") + + COUNT=0 + while [ -L "$TARGET_FILE" -a $COUNT -lt 100 ] + do + TARGET_FILE=$(readlink "$TARGET_FILE") + cd "$(dirname "$TARGET_FILE")" + TARGET_FILE=$(basename "$TARGET_FILE") + COUNT=$(($COUNT + 1)) + done + + # make sure we grab the actual windows path, instead of cygwin's path. + if [[ "x$FIX_CYGPATH" != "x" ]]; then + echo "$(cygwinpath "$(pwd -P)/$TARGET_FILE")" + else + echo "$(pwd -P)/$TARGET_FILE" + fi +) +} + + +# Uses uname to detect if we're in the odd cygwin environment. +is_cygwin() { + local os=$(uname -s) + case "$os" in + CYGWIN*) return 0 ;; + *) return 1 ;; + esac +} + +# TODO - Use nicer bash-isms here. +CYGWIN_FLAG=$(if is_cygwin; then echo true; else echo false; fi) + + +# This can fix cygwin style /cygdrive paths so we get the +# windows style paths. +cygwinpath() { + local file="$1" + if [[ "$CYGWIN_FLAG" == "true" ]]; then + echo $(cygpath -w $file) + else + echo $file + fi +} + +# Make something URI friendly +make_url() { + url="$1" + local nospaces=${url// /%20} + if is_cygwin; then + echo "/${nospaces//\\//}" + else + echo "$nospaces" + fi +} + +declare -a residual_args +declare -a java_args +declare -a scalac_args +declare -a sbt_commands +declare java_cmd=java +declare java_version +declare -r real_script_path="$(realpath "$0")" +declare -r sbt_home="$(realpath "$(dirname "$(dirname "$real_script_path")")")" +declare -r sbt_bin_dir="$(dirname "$real_script_path")" +declare -r app_version="1.3.10" + +declare -r script_name=activator +declare -r java_opts=( "${ACTIVATOR_OPTS[@]}" "${SBT_OPTS[@]}" "${JAVA_OPTS[@]}" "${java_opts[@]}" ) +userhome="$HOME" +if is_cygwin; then + # cygwin sets home to something f-d up, set to real windows homedir + userhome="$USERPROFILE" +fi +declare -r activator_user_home_dir="${userhome}/.activator" +declare -r java_opts_config_home="${activator_user_home_dir}/activatorconfig.txt" +declare -r java_opts_config_version="${activator_user_home_dir}/${app_version}/activatorconfig.txt" + +echoerr () { + echo 1>&2 "$@" +} +vlog () { + [[ $verbose || $debug ]] && echoerr "$@" +} +dlog () { + [[ $debug ]] && echoerr "$@" +} + +jar_file () { + echo "$(cygwinpath "${sbt_home}/libexec/activator-launch-${app_version}.jar")" +} + +acquire_sbt_jar () { + sbt_jar="$(jar_file)" + + if [[ ! -f "$sbt_jar" ]]; then + echoerr "Could not find launcher jar: $sbt_jar" + exit 2 + fi +} + +execRunner () { + # print the arguments one to a line, quoting any containing spaces + [[ $verbose || $debug ]] && echo "# Executing command line:" && { + for arg; do + if printf "%s\n" "$arg" | grep -q ' '; then + printf "\"%s\"\n" "$arg" + else + printf "%s\n" "$arg" + fi + done + echo "" + } + + # THis used to be exec, but we loose the ability to re-hook stty then + # for cygwin... Maybe we should flag the feature here... + "$@" +} + +addJava () { + dlog "[addJava] arg = '$1'" + java_args=( "${java_args[@]}" "$1" ) +} +addSbt () { + dlog "[addSbt] arg = '$1'" + sbt_commands=( "${sbt_commands[@]}" "$1" ) +} +addResidual () { + dlog "[residual] arg = '$1'" + residual_args=( "${residual_args[@]}" "$1" ) +} +addDebugger () { + addJava "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$1" +} + +get_mem_opts () { + # if we detect any of these settings in ${JAVA_OPTS} we need to NOT output our settings. + # The reason is the Xms/Xmx, if they don't line up, cause errors. + if [[ "${JAVA_OPTS}" == *-Xmx* ]] || [[ "${JAVA_OPTS}" == *-Xms* ]] || [[ "${JAVA_OPTS}" == *-XX:MaxPermSize* ]] || [[ "${JAVA_OPTS}" == *-XX:MaxMetaspaceSize* ]] || [[ "${JAVA_OPTS}" == *-XX:ReservedCodeCacheSize* ]]; then + echo "" + else + # a ham-fisted attempt to move some memory settings in concert + # so they need not be messed around with individually. + local mem=${1:-1024} + local codecache=$(( $mem / 8 )) + (( $codecache > 128 )) || codecache=128 + (( $codecache < 512 )) || codecache=512 + local class_metadata_size=$(( $codecache * 2 )) + local class_metadata_opt=$([[ "$java_version" < "1.8" ]] && echo "MaxPermSize" || echo "MaxMetaspaceSize") + + echo "-Xms${mem}m -Xmx${mem}m -XX:ReservedCodeCacheSize=${codecache}m -XX:${class_metadata_opt}=${class_metadata_size}m" + fi +} + +require_arg () { + local type="$1" + local opt="$2" + local arg="$3" + if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then + echo "$opt requires <$type> argument" + exit 1 + fi +} + +is_function_defined() { + declare -f "$1" > /dev/null +} + +# If we're *not* running in a terminal, and we don't have any arguments, then we need to add the 'ui' parameter +detect_terminal_for_ui() { + [[ ! -t 0 ]] && [[ "${#residual_args}" == "0" ]] && { + addResidual "ui" + } + # SPECIAL TEST FOR MAC + [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]] && [[ "${#residual_args}" == "0" ]] && { + echo "Detected MAC OSX launched script...." + echo "Swapping to UI" + addResidual "ui" + } +} + +process_args () { + while [[ $# -gt 0 ]]; do + case "$1" in + -h|-help) usage; exit 1 ;; + -v|-verbose) verbose=1 && shift ;; + -d|-debug) debug=1 && shift ;; + + -ivy) require_arg path "$1" "$2" && addJava "-Dsbt.ivy.home=$2" && shift 2 ;; + -mem) require_arg integer "$1" "$2" && sbt_mem="$2" && shift 2 ;; + -jvm-debug) require_arg port "$1" "$2" && addDebugger $2 && shift 2 ;; + -batch) exec &1 | awk -F '"' '/version/ {print $2}') + vlog "[process_args] java_version = '$java_version'" +} + +# Detect that we have java installed. +checkJava() { + local required_version="$1" + # Now check to see if it's a good enough version + if [[ "$java_version" == "" ]]; then + echo + echo No java installations was detected. + echo Please go to http://www.java.com/getjava/ and download + echo + exit 1 + elif [[ ! "$java_version" > "$required_version" ]]; then + echo + echo The java installation you have is not up to date + echo $script_name requires at least version $required_version+, you have + echo version $java_version + echo + echo Please go to http://www.java.com/getjava/ and download + echo a valid Java Runtime and install before running $script_name. + echo + exit 1 + fi +} + + +run() { + # no jar? download it. + [[ -f "$sbt_jar" ]] || acquire_sbt_jar "$sbt_version" || { + # still no jar? uh-oh. + echo "Download failed. Obtain the sbt-launch.jar manually and place it at $sbt_jar" + exit 1 + } + + # process the combined args, then reset "$@" to the residuals + process_args "$@" + detect_terminal_for_ui + set -- "${residual_args[@]}" + argumentCount=$# + + # TODO - java check should be configurable... + checkJava "1.6" + + #If we're in cygwin, we should use the windows config, and terminal hacks + if [[ "$CYGWIN_FLAG" == "true" ]]; then + stty -icanon min 1 -echo > /dev/null 2>&1 + addJava "-Djline.terminal=jline.UnixTerminal" + addJava "-Dsbt.cygwin=true" + fi + + # run sbt + execRunner "$java_cmd" \ + "-Dactivator.home=$(make_url "$sbt_home")" \ + ${SBT_OPTS:-$default_sbt_opts} \ + $(get_mem_opts $sbt_mem) \ + ${JAVA_OPTS} \ + ${java_args[@]} \ + -jar "$sbt_jar" \ + "${sbt_commands[@]}" \ + "${residual_args[@]}" + + exit_code=$? + + # Clean up the terminal from cygwin hacks. + if [[ "$CYGWIN_FLAG" == "true" ]]; then + stty icanon echo > /dev/null 2>&1 + fi + exit $exit_code +} + + +declare -r noshare_opts="-Dsbt.global.base=project/.sbtboot -Dsbt.boot.directory=project/.boot -Dsbt.ivy.home=project/.ivy" +declare -r sbt_opts_file=".sbtopts" +declare -r etc_sbt_opts_file="${sbt_home}/conf/sbtopts" +declare -r win_sbt_opts_file="${sbt_home}/conf/sbtconfig.txt" + +usage() { + cat < path to global settings/plugins directory (default: ~/.sbt) + -sbt-boot path to shared boot directory (default: ~/.sbt/boot in 0.11 series) + -ivy path to local Ivy repository (default: ~/.ivy2) + -mem set memory options (default: $sbt_mem, which is $(get_mem_opts $sbt_mem)) + -no-share use all local caches; no sharing + -no-global uses global caches, but does not use global ~/.sbt directory. + -jvm-debug Turn on JVM debugging, open at the given port. + -batch Disable interactive mode + + # sbt version (default: from project/build.properties if present, else latest release) + -sbt-version use the specified version of sbt + -sbt-jar use the specified jar as the sbt launcher + -sbt-rc use an RC version of sbt + -sbt-snapshot use a snapshot version of sbt + + # java version (default: java from PATH, currently $(java -version 2>&1 | grep version)) + -java-home alternate JAVA_HOME + + # jvm options and output control + JAVA_OPTS environment variable, if unset uses "$java_opts" + SBT_OPTS environment variable, if unset uses "$default_sbt_opts" + ACTIVATOR_OPTS Environment variable, if unset uses "" + .sbtopts if this file exists in the current directory, it is + prepended to the runner args + /etc/sbt/sbtopts if this file exists, it is prepended to the runner args + -Dkey=val pass -Dkey=val directly to the java runtime + -J-X pass option -X directly to the java runtime + (-J is stripped) + -S-X add -X to sbt's scalacOptions (-S is stripped) + +In the case of duplicated or conflicting options, the order above +shows precedence: JAVA_OPTS lowest, command line options highest. +EOM +} + + + +process_my_args () { + while [[ $# -gt 0 ]]; do + case "$1" in + -no-colors) addJava "-Dsbt.log.noformat=true" && shift ;; + -no-share) addJava "$noshare_opts" && shift ;; + -no-global) addJava "-Dsbt.global.base=$(pwd)/project/.sbtboot" && shift ;; + -sbt-boot) require_arg path "$1" "$2" && addJava "-Dsbt.boot.directory=$2" && shift 2 ;; + -sbt-dir) require_arg path "$1" "$2" && addJava "-Dsbt.global.base=$2" && shift 2 ;; + -debug-inc) addJava "-Dxsbt.inc.debug=true" && shift ;; + -batch) exec ^&1') do ( + if %%~j==java set JAVAINSTALLED=1 + if %%~j==openjdk set JAVAINSTALLED=1 +) + +rem Detect the same thing about javac +if "%_JAVACCMD%"=="" ( + if not "%JAVA_HOME%"=="" ( + if exist "%JAVA_HOME%\bin\javac.exe" set "_JAVACCMD=%JAVA_HOME%\bin\javac.exe" + ) +) +if "%_JAVACCMD%"=="" set _JAVACCMD=javac +for /F %%j in ('"%_JAVACCMD%" -version 2^>^&1') do ( + if %%~j==javac set JAVACINSTALLED=1 +) + +rem BAT has no logical or, so we do it OLD SCHOOL! Oppan Redmond Style +set JAVAOK=true +if not defined JAVAINSTALLED set JAVAOK=false +if not defined JAVACINSTALLED set JAVAOK=false + +if "%JAVAOK%"=="false" ( + echo. + echo A Java JDK is not installed or can't be found. + if not "%JAVA_HOME%"=="" ( + echo JAVA_HOME = "%JAVA_HOME%" + ) + echo. + echo Please go to + echo http://www.oracle.com/technetwork/java/javase/downloads/index.html + echo and download a valid Java JDK and install before running Activator. + echo. + echo If you think this message is in error, please check + echo your environment variables to see if "java.exe" and "javac.exe" are + echo available via JAVA_HOME or PATH. + echo. + if defined DOUBLECLICKED pause + exit /B 1 +) + +rem Check what Java version is being used to determine what memory options to use +for /f "tokens=3" %%g in ('java -version 2^>^&1 ^| findstr /i "version"') do ( + set JAVA_VERSION=%%g +) + +rem Strips away the " characters +set JAVA_VERSION=%JAVA_VERSION:"=% + +rem TODO Check if there are existing mem settings in JAVA_OPTS/CFG_OPTS and use those instead of the below +for /f "delims=. tokens=1-3" %%v in ("%JAVA_VERSION%") do ( + set MAJOR=%%v + set MINOR=%%w + set BUILD=%%x + + set META_SIZE=-XX:MetaspaceSize=64M -XX:MaxMetaspaceSize=256M + if "!MINOR!" LSS "8" ( + set META_SIZE=-XX:PermSize=64M -XX:MaxPermSize=256M + ) + + set MEM_OPTS=!META_SIZE! + ) + +rem We use the value of the JAVA_OPTS environment variable if defined, rather than the config. +set _JAVA_OPTS=%JAVA_OPTS% +if "%_JAVA_OPTS%"=="" set _JAVA_OPTS=%CFG_OPTS% + +set DEBUG_OPTS= + +rem Loop through the arguments, building remaining args in args variable +set args= +:argsloop +if not "%~1"=="" ( + rem Checks if the argument contains "-D" and if true, adds argument 1 with 2 and puts an equal sign between them. + rem This is done since batch considers "=" to be a delimiter so we need to circumvent this behavior with a small hack. + set arg1=%~1 + if "!arg1:~0,2!"=="-D" ( + set "args=%args% "%~1"="%~2"" + shift + shift + goto argsloop + ) + + if "%~1"=="-jvm-debug" ( + if not "%~2"=="" ( + rem This piece of magic somehow checks that an argument is a number + for /F "delims=0123456789" %%i in ("%~2") do ( + set var="%%i" + ) + if defined var ( + rem Not a number, assume no argument given and default to 9999 + set JPDA_PORT=9999 + ) else ( + rem Port was given, shift arguments + set JPDA_PORT=%~2 + shift + ) + ) else ( + set JPDA_PORT=9999 + ) + shift + + set DEBUG_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=!JPDA_PORT! + goto argsloop + ) + rem else + set "args=%args% "%~1"" + shift + goto argsloop +) + +:run + +if "!args!"=="" ( + if defined DOUBLECLICKED ( + set CMDS="ui" + ) else set CMDS=!args! +) else set CMDS=!args! + +rem We add a / in front, so we get file:///C: instead of file://C: +rem Java considers the later a UNC path. +rem We also attempt a solid effort at making it URI friendly. +rem We don't even bother with UNC paths. +set JAVA_FRIENDLY_HOME_1=/!ACTIVATOR_HOME:\=/! +set JAVA_FRIENDLY_HOME=/!JAVA_FRIENDLY_HOME_1: =%%20! + +rem Checks if the command contains spaces to know if it should be wrapped in quotes or not +set NON_SPACED_CMD=%_JAVACMD: =% +if "%_JAVACMD%"=="%NON_SPACED_CMD%" %_JAVACMD% %DEBUG_OPTS% %MEM_OPTS% %ACTIVATOR_OPTS% %SBT_OPTS% %_JAVA_OPTS% "-Dactivator.home=%JAVA_FRIENDLY_HOME%" -jar "%ACTIVATOR_HOME%\libexec\%ACTIVATOR_LAUNCH_JAR%" %CMDS% +if NOT "%_JAVACMD%"=="%NON_SPACED_CMD%" "%_JAVACMD%" %DEBUG_OPTS% %MEM_OPTS% %ACTIVATOR_OPTS% %SBT_OPTS% %_JAVA_OPTS% "-Dactivator.home=%JAVA_FRIENDLY_HOME%" -jar "%ACTIVATOR_HOME%\libexec\%ACTIVATOR_LAUNCH_JAR%" %CMDS% + +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end + +@endlocal + +exit /B %ERROR_CODE% diff --git a/play-framework/routing-in-play/build.sbt b/play-framework/routing-in-play/build.sbt new file mode 100644 index 0000000000..083d071676 --- /dev/null +++ b/play-framework/routing-in-play/build.sbt @@ -0,0 +1,13 @@ +name := """webapp""" + +version := "1.0-SNAPSHOT" + +lazy val root = (project in file(".")).enablePlugins(PlayJava) + +scalaVersion := "2.11.7" + +libraryDependencies ++= Seq( + javaJdbc, + cache, + javaWs +) diff --git a/play-framework/routing-in-play/conf/application.conf b/play-framework/routing-in-play/conf/application.conf new file mode 100644 index 0000000000..489d3f9b3e --- /dev/null +++ b/play-framework/routing-in-play/conf/application.conf @@ -0,0 +1,353 @@ +# This is the main configuration file for the application. +# https://www.playframework.com/documentation/latest/ConfigFile +# ~~~~~ +# Play uses HOCON as its configuration file format. HOCON has a number +# of advantages over other config formats, but there are two things that +# can be used when modifying settings. +# +# You can include other configuration files in this main application.conf file: +#include "extra-config.conf" +# +# You can declare variables and substitute for them: +#mykey = ${some.value} +# +# And if an environment variable exists when there is no other subsitution, then +# HOCON will fall back to substituting environment variable: +#mykey = ${JAVA_HOME} + +## Akka +# https://www.playframework.com/documentation/latest/ScalaAkka#Configuration +# https://www.playframework.com/documentation/latest/JavaAkka#Configuration +# ~~~~~ +# Play uses Akka internally and exposes Akka Streams and actors in Websockets and +# other streaming HTTP responses. +akka { + # "akka.log-config-on-start" is extraordinarly useful because it log the complete + # configuration at INFO level, including defaults and overrides, so it s worth + # putting at the very top. + # + # Put the following in your conf/logback.xml file: + # + # + # + # And then uncomment this line to debug the configuration. + # + #log-config-on-start = true +} + +## Secret key +# http://www.playframework.com/documentation/latest/ApplicationSecret +# ~~~~~ +# The secret key is used to sign Play's session cookie. +# This must be changed for production, but we don't recommend you change it in this file. +play.crypto.secret = "changeme" + +## Modules +# https://www.playframework.com/documentation/latest/Modules +# ~~~~~ +# Control which modules are loaded when Play starts. Note that modules are +# the replacement for "GlobalSettings", which are deprecated in 2.5.x. +# Please see https://www.playframework.com/documentation/latest/GlobalSettings +# for more information. +# +# You can also extend Play functionality by using one of the publically available +# Play modules: https://playframework.com/documentation/latest/ModuleDirectory +play.modules { + # By default, Play will load any class called Module that is defined + # in the root package (the "app" directory), or you can define them + # explicitly below. + # If there are any built-in modules that you want to disable, you can list them here. + #enabled += my.application.Module + + # If there are any built-in modules that you want to disable, you can list them here. + #disabled += "" +} + +## IDE +# https://www.playframework.com/documentation/latest/IDE +# ~~~~~ +# Depending on your IDE, you can add a hyperlink for errors that will jump you +# directly to the code location in the IDE in dev mode. The following line makes +# use of the IntelliJ IDEA REST interface: +#play.editor="http://localhost:63342/api/file/?file=%s&line=%s" + +## Internationalisation +# https://www.playframework.com/documentation/latest/JavaI18N +# https://www.playframework.com/documentation/latest/ScalaI18N +# ~~~~~ +# Play comes with its own i18n settings, which allow the user's preferred language +# to map through to internal messages, or allow the language to be stored in a cookie. +play.i18n { + # The application languages + langs = [ "en" ] + + # Whether the language cookie should be secure or not + #langCookieSecure = true + + # Whether the HTTP only attribute of the cookie should be set to true + #langCookieHttpOnly = true +} + +## Play HTTP settings +# ~~~~~ +play.http { + ## Router + # https://www.playframework.com/documentation/latest/JavaRouting + # https://www.playframework.com/documentation/latest/ScalaRouting + # ~~~~~ + # Define the Router object to use for this application. + # This router will be looked up first when the application is starting up, + # so make sure this is the entry point. + # Furthermore, it's assumed your route file is named properly. + # So for an application router like `my.application.Router`, + # you may need to define a router file `conf/my.application.routes`. + # Default to Routes in the root package (aka "apps" folder) (and conf/routes) + #router = my.application.Router + + ## Action Creator + # https://www.playframework.com/documentation/latest/JavaActionCreator + # ~~~~~ + #actionCreator = null + + ## ErrorHandler + # https://www.playframework.com/documentation/latest/JavaRouting + # https://www.playframework.com/documentation/latest/ScalaRouting + # ~~~~~ + # If null, will attempt to load a class called ErrorHandler in the root package, + #errorHandler = null + + ## Filters + # https://www.playframework.com/documentation/latest/ScalaHttpFilters + # https://www.playframework.com/documentation/latest/JavaHttpFilters + # ~~~~~ + # Filters run code on every request. They can be used to perform + # common logic for all your actions, e.g. adding common headers. + # Defaults to "Filters" in the root package (aka "apps" folder) + # Alternatively you can explicitly register a class here. + #filters = my.application.Filters + + ## Session & Flash + # https://www.playframework.com/documentation/latest/JavaSessionFlash + # https://www.playframework.com/documentation/latest/ScalaSessionFlash + # ~~~~~ + session { + # Sets the cookie to be sent only over HTTPS. + #secure = true + + # Sets the cookie to be accessed only by the server. + #httpOnly = true + + # Sets the max-age field of the cookie to 5 minutes. + # NOTE: this only sets when the browser will discard the cookie. Play will consider any + # cookie value with a valid signature to be a valid session forever. To implement a server side session timeout, + # you need to put a timestamp in the session and check it at regular intervals to possibly expire it. + #maxAge = 300 + + # Sets the domain on the session cookie. + #domain = "example.com" + } + + flash { + # Sets the cookie to be sent only over HTTPS. + #secure = true + + # Sets the cookie to be accessed only by the server. + #httpOnly = true + } +} + +## Netty Provider +# https://www.playframework.com/documentation/latest/SettingsNetty +# ~~~~~ +play.server.netty { + # Whether the Netty wire should be logged + #log.wire = true + + # If you run Play on Linux, you can use Netty's native socket transport + # for higher performance with less garbage. + #transport = "native" +} + +## WS (HTTP Client) +# https://www.playframework.com/documentation/latest/ScalaWS#Configuring-WS +# ~~~~~ +# The HTTP client primarily used for REST APIs. The default client can be +# configured directly, but you can also create different client instances +# with customized settings. You must enable this by adding to build.sbt: +# +# libraryDependencies += ws // or javaWs if using java +# +play.ws { + # Sets HTTP requests not to follow 302 requests + #followRedirects = false + + # Sets the maximum number of open HTTP connections for the client. + #ahc.maxConnectionsTotal = 50 + + ## WS SSL + # https://www.playframework.com/documentation/latest/WsSSL + # ~~~~~ + ssl { + # Configuring HTTPS with Play WS does not require programming. You can + # set up both trustManager and keyManager for mutual authentication, and + # turn on JSSE debugging in development with a reload. + #debug.handshake = true + #trustManager = { + # stores = [ + # { type = "JKS", path = "exampletrust.jks" } + # ] + #} + } +} + +## Cache +# https://www.playframework.com/documentation/latest/JavaCache +# https://www.playframework.com/documentation/latest/ScalaCache +# ~~~~~ +# Play comes with an integrated cache API that can reduce the operational +# overhead of repeated requests. You must enable this by adding to build.sbt: +# +# libraryDependencies += cache +# +play.cache { + # If you want to bind several caches, you can bind the individually + #bindCaches = ["db-cache", "user-cache", "session-cache"] +} + +## Filters +# https://www.playframework.com/documentation/latest/Filters +# ~~~~~ +# There are a number of built-in filters that can be enabled and configured +# to give Play greater security. You must enable this by adding to build.sbt: +# +# libraryDependencies += filters +# +play.filters { + ## CORS filter configuration + # https://www.playframework.com/documentation/latest/CorsFilter + # ~~~~~ + # CORS is a protocol that allows web applications to make requests from the browser + # across different domains. + # NOTE: You MUST apply the CORS configuration before the CSRF filter, as CSRF has + # dependencies on CORS settings. + cors { + # Filter paths by a whitelist of path prefixes + #pathPrefixes = ["/some/path", ...] + + # The allowed origins. If null, all origins are allowed. + #allowedOrigins = ["http://www.example.com"] + + # The allowed HTTP methods. If null, all methods are allowed + #allowedHttpMethods = ["GET", "POST"] + } + + ## CSRF Filter + # https://www.playframework.com/documentation/latest/ScalaCsrf#Applying-a-global-CSRF-filter + # https://www.playframework.com/documentation/latest/JavaCsrf#Applying-a-global-CSRF-filter + # ~~~~~ + # Play supports multiple methods for verifying that a request is not a CSRF request. + # The primary mechanism is a CSRF token. This token gets placed either in the query string + # or body of every form submitted, and also gets placed in the users session. + # Play then verifies that both tokens are present and match. + csrf { + # Sets the cookie to be sent only over HTTPS + #cookie.secure = true + + # Defaults to CSRFErrorHandler in the root package. + #errorHandler = MyCSRFErrorHandler + } + + ## Security headers filter configuration + # https://www.playframework.com/documentation/latest/SecurityHeaders + # ~~~~~ + # Defines security headers that prevent XSS attacks. + # If enabled, then all options are set to the below configuration by default: + headers { + # The X-Frame-Options header. If null, the header is not set. + #frameOptions = "DENY" + + # The X-XSS-Protection header. If null, the header is not set. + #xssProtection = "1; mode=block" + + # The X-Content-Type-Options header. If null, the header is not set. + #contentTypeOptions = "nosniff" + + # The X-Permitted-Cross-Domain-Policies header. If null, the header is not set. + #permittedCrossDomainPolicies = "master-only" + + # The Content-Security-Policy header. If null, the header is not set. + #contentSecurityPolicy = "default-src 'self'" + } + + ## Allowed hosts filter configuration + # https://www.playframework.com/documentation/latest/AllowedHostsFilter + # ~~~~~ + # Play provides a filter that lets you configure which hosts can access your application. + # This is useful to prevent cache poisoning attacks. + hosts { + # Allow requests to example.com, its subdomains, and localhost:9000. + #allowed = [".example.com", "localhost:9000"] + } +} + +## Evolutions +# https://www.playframework.com/documentation/latest/Evolutions +# ~~~~~ +# Evolutions allows database scripts to be automatically run on startup in dev mode +# for database migrations. You must enable this by adding to build.sbt: +# +# libraryDependencies += evolutions +# +play.evolutions { + # You can disable evolutions for a specific datasource if necessary + #db.default.enabled = false +} + +## Database Connection Pool +# https://www.playframework.com/documentation/latest/SettingsJDBC +# ~~~~~ +# Play doesn't require a JDBC database to run, but you can easily enable one. +# +# libraryDependencies += jdbc +# +play.db { + # The combination of these two settings results in "db.default" as the + # default JDBC pool: + #config = "db" + #default = "default" + + # Play uses HikariCP as the default connection pool. You can override + # settings by changing the prototype: + prototype { + # Sets a fixed JDBC connection pool size of 50 + #hikaricp.minimumIdle = 50 + #hikaricp.maximumPoolSize = 50 + } +} + +## JDBC Datasource +# https://www.playframework.com/documentation/latest/JavaDatabase +# https://www.playframework.com/documentation/latest/ScalaDatabase +# ~~~~~ +# Once JDBC datasource is set up, you can work with several different +# database options: +# +# Slick (Scala preferred option): https://www.playframework.com/documentation/latest/PlaySlick +# JPA (Java preferred option): https://playframework.com/documentation/latest/JavaJPA +# EBean: https://playframework.com/documentation/latest/JavaEbean +# Anorm: https://www.playframework.com/documentation/latest/ScalaAnorm +# +db { + # You can declare as many datasources as you want. + # By convention, the default datasource is named `default` + + # https://www.playframework.com/documentation/latest/Developing-with-the-H2-Database + #default.driver = org.h2.Driver + #default.url = "jdbc:h2:mem:play" + #default.username = sa + #default.password = "" + + # You can turn on SQL logging for any datasource + # https://www.playframework.com/documentation/latest/Highlights25#Logging-SQL-statements + #default.logSql=true +} diff --git a/play-framework/routing-in-play/conf/logback.xml b/play-framework/routing-in-play/conf/logback.xml new file mode 100644 index 0000000000..86ec12c0af --- /dev/null +++ b/play-framework/routing-in-play/conf/logback.xml @@ -0,0 +1,41 @@ + + + + + + + ${application.home:-.}/logs/application.log + + %date [%level] from %logger in %thread - %message%n%xException + + + + + + %coloredLevel %logger{15} - %message%n%xException{10} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/play-framework/routing-in-play/conf/routes b/play-framework/routing-in-play/conf/routes new file mode 100644 index 0000000000..f72d8a1a14 --- /dev/null +++ b/play-framework/routing-in-play/conf/routes @@ -0,0 +1,7 @@ +GET / controllers.HomeController.index(author="Baeldung",id:Int?=1) +GET /:author controllers.HomeController.index(author,id:Int?=1) +GET /greet/:name/:age controllers.HomeController.greet(name,age:Integer) +GET /square/$num<[0-9]+> controllers.HomeController.squareMe(num:Long) +# Map static resources from the /public folder to the /assets URL path +GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset) +GET /*data controllers.HomeController.introduceMe(data) diff --git a/play-framework/routing-in-play/libexec/activator-launch-1.3.10.jar b/play-framework/routing-in-play/libexec/activator-launch-1.3.10.jar new file mode 100644 index 0000000000..69050e7dec Binary files /dev/null and b/play-framework/routing-in-play/libexec/activator-launch-1.3.10.jar differ diff --git a/play-framework/routing-in-play/project/build.properties b/play-framework/routing-in-play/project/build.properties new file mode 100644 index 0000000000..6d22e3f2d1 --- /dev/null +++ b/play-framework/routing-in-play/project/build.properties @@ -0,0 +1,4 @@ +#Activator-generated Properties +#Fri Sep 30 14:25:10 EAT 2016 +template.uuid=26c759a5-daf0-4e02-bcfa-ac69725267c0 +sbt.version=0.13.11 diff --git a/play-framework/routing-in-play/project/plugins.sbt b/play-framework/routing-in-play/project/plugins.sbt new file mode 100644 index 0000000000..e8e7f602f7 --- /dev/null +++ b/play-framework/routing-in-play/project/plugins.sbt @@ -0,0 +1,21 @@ +// The Play plugin +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.8") + +// Web plugins +addSbtPlugin("com.typesafe.sbt" % "sbt-coffeescript" % "1.0.0") +addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.1.0") +addSbtPlugin("com.typesafe.sbt" % "sbt-jshint" % "1.0.4") +addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.8") +addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.1.1") +addSbtPlugin("com.typesafe.sbt" % "sbt-mocha" % "1.1.0") +addSbtPlugin("org.irundaia.sbt" % "sbt-sassify" % "1.4.6") + +// Play enhancer - this automatically generates getters/setters for public fields +// and rewrites accessors of these fields to use the getters/setters. Remove this +// plugin if you prefer not to have this feature, or disable on a per project +// basis using disablePlugins(PlayEnhancer) in your build.sbt +addSbtPlugin("com.typesafe.sbt" % "sbt-play-enhancer" % "1.1.0") + +// Play Ebean support, to enable, uncomment this line, and enable in your build.sbt using +// enablePlugins(PlayEbean). +// addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "3.0.2") diff --git a/play-framework/routing-in-play/public/images/favicon.png b/play-framework/routing-in-play/public/images/favicon.png new file mode 100644 index 0000000000..c7d92d2ae4 Binary files /dev/null and b/play-framework/routing-in-play/public/images/favicon.png differ diff --git a/play-framework/routing-in-play/public/javascripts/hello.js b/play-framework/routing-in-play/public/javascripts/hello.js new file mode 100644 index 0000000000..02ee13c7ca --- /dev/null +++ b/play-framework/routing-in-play/public/javascripts/hello.js @@ -0,0 +1,3 @@ +if (window.console) { + console.log("Welcome to your Play application's JavaScript!"); +} diff --git a/play-framework/routing-in-play/public/stylesheets/main.css b/play-framework/routing-in-play/public/stylesheets/main.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/play-framework/routing-in-play/test/ApplicationTest.java b/play-framework/routing-in-play/test/ApplicationTest.java new file mode 100644 index 0000000000..3d7c4875aa --- /dev/null +++ b/play-framework/routing-in-play/test/ApplicationTest.java @@ -0,0 +1,45 @@ +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.databind.JsonNode; +import org.junit.*; + +import play.mvc.*; +import play.test.*; +import play.data.DynamicForm; +import play.data.validation.ValidationError; +import play.data.validation.Constraints.RequiredValidator; +import play.i18n.Lang; +import play.libs.F; +import play.libs.F.*; +import play.twirl.api.Content; + +import static play.test.Helpers.*; +import static org.junit.Assert.*; + + +/** + * + * Simple (JUnit) tests that can call all parts of a play app. + * If you are interested in mocking a whole application, see the wiki for more details. + * + */ +public class ApplicationTest { + + @Test + public void simpleCheck() { + int a = 1 + 1; + assertEquals(2, a); + } + + @Test + public void renderTemplate() { + Content html = views.html.index.render("Your new application is ready."); + assertEquals("text/html", html.contentType()); + assertTrue(html.body().contains("Your new application is ready.")); + } + + +} diff --git a/play-framework/routing-in-play/test/IntegrationTest.java b/play-framework/routing-in-play/test/IntegrationTest.java new file mode 100644 index 0000000000..c53c71e124 --- /dev/null +++ b/play-framework/routing-in-play/test/IntegrationTest.java @@ -0,0 +1,25 @@ +import org.junit.*; + +import play.mvc.*; +import play.test.*; + +import static play.test.Helpers.*; +import static org.junit.Assert.*; + +import static org.fluentlenium.core.filter.FilterConstructor.*; + +public class IntegrationTest { + + /** + * add your integration test here + * in this example we just check if the welcome page is being shown + */ + @Test + public void test() { + running(testServer(3333, fakeApplication(inMemoryDatabase())), HTMLUNIT, browser -> { + browser.goTo("http://localhost:3333"); + assertTrue(browser.pageSource().contains("Your new application is ready.")); + }); + } + +} diff --git a/play-framework/student-api/test/ApplicationTest.java b/play-framework/student-api/test/ApplicationTest.java new file mode 100644 index 0000000000..1133978e9a --- /dev/null +++ b/play-framework/student-api/test/ApplicationTest.java @@ -0,0 +1,172 @@ + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Arrays; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Test; +import model.Student; +import play.test.*; +import static play.test.Helpers.*; + +public class ApplicationTest{ + private static final String BASE_URL = "http://localhost:9000"; + + @Test +public void testInServer() throws Exception { + TestServer server = testServer(3333); + running(server, () -> { + try { + WSClient ws = play.libs.ws.WS.newClient(3333); + CompletionStage completionStage = ws.url("/").get(); + WSResponse response = completionStage.toCompletableFuture().get(); + ws.close(); + assertEquals(OK, response.getStatus()); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + }); +} + @Test + public void whenCreatesRecord_thenCorrect() { + Student student = new Student("jody", "west", 50); + JSONObject obj = new JSONObject(makeRequest(BASE_URL, "POST", new JSONObject(student))); + assertTrue(obj.getBoolean("isSuccessfull")); + JSONObject body = obj.getJSONObject("body"); + assertEquals(student.getAge(), body.getInt("age")); + assertEquals(student.getFirstName(), body.getString("firstName")); + assertEquals(student.getLastName(), body.getString("lastName")); + } + + @Test + public void whenDeletesCreatedRecord_thenCorrect() { + Student student = new Student("Usain", "Bolt", 25); + JSONObject ob1 = new JSONObject(makeRequest(BASE_URL, "POST", new JSONObject(student))).getJSONObject("body"); + int id = ob1.getInt("id"); + JSONObject obj1 = new JSONObject(makeRequest(BASE_URL + "/" + id, "POST", new JSONObject())); + assertTrue(obj1.getBoolean("isSuccessfull")); + makeRequest(BASE_URL + "/" + id, "DELETE", null); + JSONObject obj2 = new JSONObject(makeRequest(BASE_URL + "/" + id, "POST", new JSONObject())); + assertFalse(obj2.getBoolean("isSuccessfull")); + } + + @Test + public void whenUpdatesCreatedRecord_thenCorrect() { + Student student = new Student("john", "doe", 50); + JSONObject body1 = new JSONObject(makeRequest(BASE_URL, "POST", new JSONObject(student))).getJSONObject("body"); + assertEquals(student.getAge(), body1.getInt("age")); + int newAge = 60; + body1.put("age", newAge); + JSONObject body2 = new JSONObject(makeRequest(BASE_URL, "PUT", body1)).getJSONObject("body"); + assertFalse(student.getAge() == body2.getInt("age")); + assertTrue(newAge == body2.getInt("age")); + } + + @Test + public void whenGetsAllRecords_thenCorrect() { + Student student1 = new Student("jane", "daisy", 50); + Student student2 = new Student("john", "daniel", 60); + Student student3 = new Student("don", "mason", 55); + Student student4 = new Student("scarlet", "ohara", 90); + + makeRequest(BASE_URL, "POST", new JSONObject(student1)); + makeRequest(BASE_URL, "POST", new JSONObject(student2)); + makeRequest(BASE_URL, "POST", new JSONObject(student3)); + makeRequest(BASE_URL, "POST", new JSONObject(student4)); + + JSONObject objects = new JSONObject(makeRequest(BASE_URL, "GET", null)); + assertTrue(objects.getBoolean("isSuccessfull")); + JSONArray array = objects.getJSONArray("body"); + assertTrue(array.length() >= 4); + } + + public static String makeRequest(String myUrl, String httpMethod, JSONObject parameters) { + + URL url = null; + try { + url = new URL(myUrl); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + HttpURLConnection conn = null; + try { + + conn = (HttpURLConnection) url.openConnection(); + } catch (IOException e) { + e.printStackTrace(); + } + conn.setDoInput(true); + + conn.setReadTimeout(10000); + + conn.setRequestProperty("Content-Type", "application/json"); + DataOutputStream dos = null; + int respCode = 0; + String inputString = null; + try { + conn.setRequestMethod(httpMethod); + + if (Arrays.asList("POST", "PUT").contains(httpMethod)) { + String params = parameters.toString(); + + conn.setDoOutput(true); + + dos = new DataOutputStream(conn.getOutputStream()); + dos.writeBytes(params); + dos.flush(); + dos.close(); + } + respCode = conn.getResponseCode(); + if (respCode != 200 && respCode != 201) { + String error = inputStreamToString(conn.getErrorStream()); + return error; + } + inputString = inputStreamToString(conn.getInputStream()); + + } catch (IOException e) { + + e.printStackTrace(); + } + return inputString; + } + + public static String inputStreamToString(InputStream is) { + BufferedReader br = null; + StringBuilder sb = new StringBuilder(); + + String line; + try { + + br = new BufferedReader(new InputStreamReader(is)); + while ((line = br.readLine()) != null) { + sb.append(line); + } + + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + return sb.toString(); + + } +} diff --git a/pom.xml b/pom.xml index d2f5d83b46..bd626b3ad0 100644 --- a/pom.xml +++ b/pom.xml @@ -1,3 +1,4 @@ + 4.0.0 com.baeldung @@ -8,79 +9,116 @@ pom - + UTF-8 - + - assertj + annotations apache-cxf - apache-fop - core-java - core-java-8 - couchbase-sdk-intro - couchbase-sdk-spring-service + apache-fop + assertj + autovalue + + cdi + + core-java + couchbase-sdk + + deltaspike + dozer + + feign + flyway + + - dependency-injection - gatling gson - gson-jackson-performance guava guava18 guava19 + handling-spring-static-resources + hazelcast httpclient + hystrix + + immutables + jackson + java-cassandra javaxval + jee7 jjwt - jooq-spring jpa-storedprocedure - json + jsf json-path + json junit5 + + log4j + lombok + + mapstruct mockito mocks - jee7schedule - + + orika + + patterns + querydsl + + redis rest-assured rest-testing resteasy - log4j + selenium-junit-testng + spring-akka spring-all spring-apache-camel spring-autowire spring-batch spring-boot + spring-cloud-data-flow + spring-cloud + spring-core spring-cucumber spring-data-cassandra spring-data-couchbase-2 - spring-data-couchbase-2b + spring-data-dynamodb spring-data-elasticsearch - spring-data-neo4j spring-data-mongodb + spring-data-neo4j spring-data-redis spring-data-rest + spring-data-solr + spring-dispatcher-servlet spring-exceptions spring-freemarker spring-hibernate3 spring-hibernate4 + spring-integration + spring-jms + spring-jooq spring-jpa spring-katharsis spring-mockito spring-mvc-java spring-mvc-no-xml + spring-mvc-tiles + spring-mvc-velocity + spring-mvc-web-vs-initializer spring-mvc-xml spring-openid spring-protobuf spring-quartz - spring-spel - spring-rest + spring-rest-angular spring-rest-docs - + spring-rest spring-security-basic-auth spring-security-custom-permission spring-security-mvc-custom @@ -89,22 +127,26 @@ spring-security-mvc-login spring-security-mvc-persisted-remember-me spring-security-mvc-session - spring-security-rest spring-security-rest-basic-auth spring-security-rest-custom spring-security-rest-digest-auth spring-security-rest-full + spring-security-rest + spring-security-x509 + spring-session + spring-spel spring-thymeleaf + spring-userservice spring-zuul - jsf + + testing + + wicket + xml - lombok - redis - webjars - - mutation-testing - spring-mvc-velocity + xmlunit2 xstream - + pdf + - + \ No newline at end of file diff --git a/querydsl/README.md b/querydsl/README.md new file mode 100644 index 0000000000..ef9f8f894c --- /dev/null +++ b/querydsl/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Intro to Querydsl](http://www.baeldung.com/intro-to-querydsl) diff --git a/querydsl/pom.xml b/querydsl/pom.xml index bed0cf90e5..13528526ea 100644 --- a/querydsl/pom.xml +++ b/querydsl/pom.xml @@ -20,6 +20,7 @@ 5.2.1.Final 4.1.3 1.7.21 + 2.19.1 @@ -166,7 +167,55 @@ + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + \ No newline at end of file diff --git a/querydsl/src/test/java/org/baeldung/dao/PersonDaoTest.java b/querydsl/src/test/java/org/baeldung/dao/PersonDaoIntegrationTest.java similarity index 98% rename from querydsl/src/test/java/org/baeldung/dao/PersonDaoTest.java rename to querydsl/src/test/java/org/baeldung/dao/PersonDaoIntegrationTest.java index 0e5996a8c8..a666aea8da 100644 --- a/querydsl/src/test/java/org/baeldung/dao/PersonDaoTest.java +++ b/querydsl/src/test/java/org/baeldung/dao/PersonDaoIntegrationTest.java @@ -17,7 +17,7 @@ import junit.framework.Assert; @RunWith(SpringJUnit4ClassRunner.class) @Transactional @TransactionConfiguration(defaultRollback = true) -public class PersonDaoTest { +public class PersonDaoIntegrationTest { @Autowired private PersonDao personDao; diff --git a/raml/resource-types-and-traits/README.md b/raml/resource-types-and-traits/README.md new file mode 100644 index 0000000000..72e7b454d6 --- /dev/null +++ b/raml/resource-types-and-traits/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Eliminate Redundancies in RAML with Resource Types and Traits](http://www.baeldung.com/simple-raml-with-resource-types-and-traits) diff --git a/redis/src/test/java/com/baeldung/JedisTest.java b/redis/src/test/java/com/baeldung/JedisTest.java index 766fd7b5e9..582bb266aa 100644 --- a/redis/src/test/java/com/baeldung/JedisTest.java +++ b/redis/src/test/java/com/baeldung/JedisTest.java @@ -1,28 +1,15 @@ package com.baeldung; +import org.junit.*; +import redis.clients.jedis.*; +import redis.embedded.RedisServer; + import java.io.IOException; import java.time.Duration; import java.util.HashMap; import java.util.Map; import java.util.Set; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; -import redis.clients.jedis.Pipeline; -import redis.clients.jedis.Response; -import redis.clients.jedis.Transaction; -import redis.embedded.RedisServer; - -/** - * Unit test for Redis Java library - Jedis. - */ public class JedisTest { private Jedis jedis; @@ -140,9 +127,9 @@ public class JedisTest { scores.put("PlayerTwo", 1500.0); scores.put("PlayerThree", 8200.0); - for (String player : scores.keySet()) { + scores.keySet().forEach(player -> { jedis.zadd(key, scores.get(player), player); - } + }); Set players = jedis.zrevrange(key, 0, 1); Assert.assertEquals("PlayerThree", players.iterator().next()); diff --git a/rest-assured/README.md b/rest-assured/README.md index e69de29bb2..50f36f61eb 100644 --- a/rest-assured/README.md +++ b/rest-assured/README.md @@ -0,0 +1,2 @@ +###Relevant Articles: +- [A Guide to REST-assured](http://www.baeldung.com/rest-assured-tutorial) diff --git a/rest-assured/pom.xml b/rest-assured/pom.xml index 47241b18bd..e2a2af9cd9 100644 --- a/rest-assured/pom.xml +++ b/rest-assured/pom.xml @@ -1,257 +1,226 @@ - 4.0.0 - com.baeldung - rest-assured - 1.0 - rest-assured - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.3 - - 8 - 8 - - - - - - - - javax.servlet - javax.servlet-api - 3.1-b06 - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + 4.0.0 + com.baeldung + rest-assured + 1.0 + rest-assured - - - javax.servlet - servlet-api - 2.5 - + + + javax.servlet + javax.servlet-api + 3.1-b06 + + + javax.servlet + servlet-api + 2.5 + + + org.eclipse.jetty + jetty-security + 9.2.0.M1 + + + org.eclipse.jetty + jetty-servlet + 9.2.0.M1 + + + org.eclipse.jetty + jetty-servlets + 9.2.0.M1 + + + org.eclipse.jetty + jetty-io + 9.2.0.M1 + + + org.eclipse.jetty + jetty-http + 9.2.0.M1 + + + org.eclipse.jetty + jetty-server + 9.2.0.M1 + + + org.eclipse.jetty + jetty-util + 9.2.0.M1 + - - - org.eclipse.jetty - jetty-security - 9.2.0.M1 - + + org.slf4j + slf4j-api + 1.7.21 + - - - org.eclipse.jetty - jetty-servlet - 9.2.0.M1 - + + log4j + log4j + 1.2.17 + + + org.slf4j + slf4j-log4j12 + 1.7.21 + - - - org.eclipse.jetty - jetty-servlets - 9.2.0.M1 - + + commons-logging + commons-logging + 1.2 + - - - org.eclipse.jetty - jetty-io - 9.2.0.M1 - + + org.apache.httpcomponents + httpcore + 4.4.5 + - - - org.eclipse.jetty - jetty-http - 9.2.0.M1 - + + org.apache.commons + commons-lang3 + 3.4 + + + com.github.fge + uri-template + 0.9 + + + com.googlecode.libphonenumber + libphonenumber + 7.4.5 + - - - org.eclipse.jetty - jetty-server - 9.2.0.M1 - + + javax.mail + mail + 1.4.7 + - - - org.eclipse.jetty - jetty-util - 9.2.0.M1 - + + joda-time + joda-time + 2.9.4 + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + - - - org.slf4j - slf4j-api - 1.7.21 - + + com.github.fge + msg-simple + 1.1 + - - - log4j - log4j - 1.2.17 - - - - org.slf4j - slf4j-log4j12 - 1.7.21 - + + com.github.fge + jackson-coreutils + 1.8 + - - - - commons-logging - commons-logging - 1.2 - + + com.google.guava + guava + ${guava.version} + + + com.github.fge + btf + 1.2 + - - org.apache.httpcomponents - httpcore - 4.4.5 - + + org.apache.httpcomponents + httpclient + 4.5.2 + - - - org.apache.commons - commons-lang3 - 3.4 - + + org.codehaus.groovy + groovy-all + 2.4.7 + - - - - com.github.fge - uri-template - 0.9 - + + com.github.tomakehurst + wiremock + 2.1.7 + + + io.rest-assured + rest-assured + 3.0.0 + test + + + io.rest-assured + json-schema-validator + 3.0.0 + + + com.github.fge + json-schema-validator + 2.2.6 + + + com.github.fge + json-schema-core + 1.2.5 + + + junit + junit + 4.3 + test + - - - com.googlecode.libphonenumber - libphonenumber - 7.4.5 - + + org.hamcrest + hamcrest-all + 1.3 + + + commons-collections + commons-collections + 3.2.2 + - - javax.mail - mail - 1.4.7 - + - - joda-time - joda-time - 2.9.4 - + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 8 + 8 + + + + - - com.fasterxml.jackson.core - jackson-annotations - 2.8.0 - + + 2.8.3 + 19.0 + - - com.fasterxml.jackson.core - jackson-databind - 2.8.0 - - - - com.fasterxml.jackson.core - jackson-core - 2.8.0 - - - - com.github.fge - msg-simple - 1.1 - - - - com.github.fge - jackson-coreutils - 1.8 - - - - - - com.google.guava - guava - 18.0 - - - com.github.fge - btf - 1.2 - - - - org.apache.httpcomponents - httpclient - 4.5.2 - - - - org.codehaus.groovy - groovy-all - 2.4.7 - - - - com.github.tomakehurst - wiremock - 2.1.7 - - - io.rest-assured - rest-assured - 3.0.0 - test - - - io.rest-assured - json-schema-validator - 3.0.0 - - - com.github.fge - json-schema-validator - 2.2.6 - - - com.github.fge - json-schema-core - 1.2.5 - - - junit - junit - 4.3 - test - - - - org.hamcrest - hamcrest-all - 1.3 - - - - commons-collections - commons-collections - 3.2.2 - - - diff --git a/rest-testing/README.md b/rest-testing/README.md index 54a2e98dda..5dd4e49162 100644 --- a/rest-testing/README.md +++ b/rest-testing/README.md @@ -7,3 +7,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [Test a REST API with Java](http://www.baeldung.com/2011/10/13/integration-testing-a-rest-api/) +- [Introduction to WireMock](http://www.baeldung.com/introduction-to-wiremock) +- [REST API Testing with Cucumber](http://www.baeldung.com/cucumber-rest-api-testing) diff --git a/rest-testing/pom.xml b/rest-testing/pom.xml index 652f2ab601..90c160af15 100644 --- a/rest-testing/pom.xml +++ b/rest-testing/pom.xml @@ -148,15 +148,57 @@ org.apache.maven.plugins maven-surefire-plugin ${maven-surefire-plugin.version} + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*UnitTest.java + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + json + + + + + + + + - 2.7.2 + 2.7.8 1.7.13 diff --git a/rest-testing/src/test/java/com/baeldung/rest/cucumber/CucumberTest.java b/rest-testing/src/test/java/com/baeldung/rest/cucumber/CucumberIntegrationTest.java similarity index 84% rename from rest-testing/src/test/java/com/baeldung/rest/cucumber/CucumberTest.java rename to rest-testing/src/test/java/com/baeldung/rest/cucumber/CucumberIntegrationTest.java index 041de592e9..f80178a43d 100644 --- a/rest-testing/src/test/java/com/baeldung/rest/cucumber/CucumberTest.java +++ b/rest-testing/src/test/java/com/baeldung/rest/cucumber/CucumberIntegrationTest.java @@ -6,5 +6,5 @@ import cucumber.api.junit.Cucumber; @RunWith(Cucumber.class) @CucumberOptions(features = "classpath:Feature") -public class CucumberTest { +public class CucumberIntegrationTest { } \ No newline at end of file diff --git a/resteasy/pom.xml b/resteasy/pom.xml index ec9e87b0d1..04e8576e1f 100644 --- a/resteasy/pom.xml +++ b/resteasy/pom.xml @@ -10,6 +10,8 @@ 3.0.14.Final + 2.19.1 + 1.6.0 @@ -23,6 +25,35 @@ 1.8 + + 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 + + + + @@ -73,5 +104,66 @@ + + + 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/resteasy/src/test/java/com/baeldung/server/RestEasyClientTest.java b/resteasy/src/test/java/com/baeldung/server/RestEasyClientLiveTest.java similarity index 61% rename from resteasy/src/test/java/com/baeldung/server/RestEasyClientTest.java rename to resteasy/src/test/java/com/baeldung/server/RestEasyClientLiveTest.java index ef18b0f23f..7e709edb96 100644 --- a/resteasy/src/test/java/com/baeldung/server/RestEasyClientTest.java +++ b/resteasy/src/test/java/com/baeldung/server/RestEasyClientLiveTest.java @@ -1,7 +1,15 @@ package com.baeldung.server; -import com.baeldung.client.ServicesInterface; -import com.baeldung.model.Movie; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.Locale; + +import javax.naming.NamingException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriBuilder; + import org.apache.commons.io.IOUtils; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; @@ -14,18 +22,13 @@ import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine; import org.junit.Before; import org.junit.Test; -import javax.naming.NamingException; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriBuilder; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.text.SimpleDateFormat; -import java.util.List; -import java.util.Locale; -public class RestEasyClientTest { +import com.baeldung.client.ServicesInterface; +import com.baeldung.model.Movie; - public static final UriBuilder FULL_PATH = UriBuilder.fromPath("http://127.0.0.1:8080/RestEasyTutorial/rest"); +public class RestEasyClientLiveTest { + + public static final UriBuilder FULL_PATH = UriBuilder.fromPath("http://127.0.0.1:8082/RestEasyTutorial/rest"); Movie transformerMovie = null; Movie batmanMovie = null; ObjectMapper jsonMapper = null; @@ -35,22 +38,22 @@ public class RestEasyClientTest { jsonMapper = new ObjectMapper().configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); jsonMapper.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); - SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH); + final SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH); jsonMapper.setDateFormat(sdf); - try (InputStream inputStream = new RestEasyClientTest().getClass().getResourceAsStream("./movies/transformer.json")) { - String transformerMovieAsString = String.format(IOUtils.toString(inputStream, StandardCharsets.UTF_8)); + try (InputStream inputStream = new RestEasyClientLiveTest().getClass().getResourceAsStream("./movies/transformer.json")) { + final String transformerMovieAsString = String.format(IOUtils.toString(inputStream, StandardCharsets.UTF_8)); transformerMovie = jsonMapper.readValue(transformerMovieAsString, Movie.class); - } catch (Exception e) { + } catch (final Exception e) { e.printStackTrace(); throw new RuntimeException("Test is going to die ...", e); } - try (InputStream inputStream = new RestEasyClientTest().getClass().getResourceAsStream("./movies/batman.json")) { - String batmanMovieAsString = String.format(IOUtils.toString(inputStream, StandardCharsets.UTF_8)); + try (InputStream inputStream = new RestEasyClientLiveTest().getClass().getResourceAsStream("./movies/batman.json")) { + final String batmanMovieAsString = String.format(IOUtils.toString(inputStream, StandardCharsets.UTF_8)); batmanMovie = jsonMapper.readValue(batmanMovieAsString, Movie.class); - } catch (Exception e) { + } catch (final Exception e) { throw new RuntimeException("Test is going to die ...", e); } } @@ -58,41 +61,41 @@ public class RestEasyClientTest { @Test public void testListAllMovies() { - ResteasyClient client = new ResteasyClientBuilder().build(); - ResteasyWebTarget target = client.target(FULL_PATH); - ServicesInterface proxy = target.proxy(ServicesInterface.class); + final ResteasyClient client = new ResteasyClientBuilder().build(); + final ResteasyWebTarget target = client.target(FULL_PATH); + final ServicesInterface proxy = target.proxy(ServicesInterface.class); Response moviesResponse = proxy.addMovie(transformerMovie); moviesResponse.close(); moviesResponse = proxy.addMovie(batmanMovie); moviesResponse.close(); - List movies = proxy.listMovies(); + final List movies = proxy.listMovies(); System.out.println(movies); } @Test public void testMovieByImdbId() { - String transformerImdbId = "tt0418279"; + final String transformerImdbId = "tt0418279"; - ResteasyClient client = new ResteasyClientBuilder().build(); - ResteasyWebTarget target = client.target(FULL_PATH); - ServicesInterface proxy = target.proxy(ServicesInterface.class); + final ResteasyClient client = new ResteasyClientBuilder().build(); + final ResteasyWebTarget target = client.target(FULL_PATH); + final ServicesInterface proxy = target.proxy(ServicesInterface.class); - Response moviesResponse = proxy.addMovie(transformerMovie); + final Response moviesResponse = proxy.addMovie(transformerMovie); moviesResponse.close(); - Movie movies = proxy.movieByImdbId(transformerImdbId); + final Movie movies = proxy.movieByImdbId(transformerImdbId); System.out.println(movies); } @Test public void testAddMovie() { - ResteasyClient client = new ResteasyClientBuilder().build(); - ResteasyWebTarget target = client.target(FULL_PATH); - ServicesInterface proxy = target.proxy(ServicesInterface.class); + final ResteasyClient client = new ResteasyClientBuilder().build(); + final ResteasyWebTarget target = client.target(FULL_PATH); + final ServicesInterface proxy = target.proxy(ServicesInterface.class); Response moviesResponse = proxy.addMovie(batmanMovie); moviesResponse.close(); @@ -109,17 +112,15 @@ public class RestEasyClientTest { @Test public void testAddMovieMultiConnection() { - PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); - CloseableHttpClient httpClient = HttpClients.custom() - .setConnectionManager(cm) - .build(); - ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient); - ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build(); - ResteasyWebTarget target = client.target(FULL_PATH); - ServicesInterface proxy = target.proxy(ServicesInterface.class); + final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); + final CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build(); + final ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient); + final ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build(); + final ResteasyWebTarget target = client.target(FULL_PATH); + final ServicesInterface proxy = target.proxy(ServicesInterface.class); - Response batmanResponse = proxy.addMovie(batmanMovie); - Response transformerResponse = proxy.addMovie(transformerMovie); + final Response batmanResponse = proxy.addMovie(batmanMovie); + final Response transformerResponse = proxy.addMovie(transformerMovie); if (batmanResponse.getStatus() != Response.Status.CREATED.getStatusCode()) { System.out.println("Batman Movie creation Failed : HTTP error code : " + batmanResponse.getStatus()); @@ -132,16 +133,14 @@ public class RestEasyClientTest { transformerResponse.close(); cm.close(); - - } @Test public void testDeleteMovie() { - ResteasyClient client = new ResteasyClientBuilder().build(); - ResteasyWebTarget target = client.target(FULL_PATH); - ServicesInterface proxy = target.proxy(ServicesInterface.class); + final ResteasyClient client = new ResteasyClientBuilder().build(); + final ResteasyWebTarget target = client.target(FULL_PATH); + final ServicesInterface proxy = target.proxy(ServicesInterface.class); Response moviesResponse = proxy.addMovie(batmanMovie); moviesResponse.close(); @@ -159,9 +158,9 @@ public class RestEasyClientTest { @Test public void testUpdateMovie() { - ResteasyClient client = new ResteasyClientBuilder().build(); - ResteasyWebTarget target = client.target(FULL_PATH); - ServicesInterface proxy = target.proxy(ServicesInterface.class); + final ResteasyClient client = new ResteasyClientBuilder().build(); + final ResteasyWebTarget target = client.target(FULL_PATH); + final ServicesInterface proxy = target.proxy(ServicesInterface.class); Response moviesResponse = proxy.addMovie(batmanMovie); moviesResponse.close(); diff --git a/selenium-junit-testng/pom.xml b/selenium-junit-testng/pom.xml new file mode 100644 index 0000000000..cc96ea8529 --- /dev/null +++ b/selenium-junit-testng/pom.xml @@ -0,0 +1,69 @@ + + 4.0.0 + com.baeldung + selenium-junit-testng + 0.0.1-SNAPSHOT + + src + + + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + true + + **/*UnitTest.java + + + + + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + + **/*LiveTest.java + + + + + + + + + + + org.seleniumhq.selenium + selenium-java + 3.0.1 + + + junit + junit + 4.12 + + + org.testng + testng + 6.9.13.6 + + + \ No newline at end of file diff --git a/selenium-junit-testng/src/main/java/com/baeldung/selenium/SeleniumExample.java b/selenium-junit-testng/src/main/java/com/baeldung/selenium/SeleniumExample.java new file mode 100644 index 0000000000..58d47c0162 --- /dev/null +++ b/selenium-junit-testng/src/main/java/com/baeldung/selenium/SeleniumExample.java @@ -0,0 +1,61 @@ +package main.java.com.baeldung.selenium; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.concurrent.TimeUnit; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.firefox.FirefoxDriver; + +public class SeleniumExample { + + private WebDriver webDriver; + private String url = "http://www.baeldung.com/"; + + public SeleniumExample() { + System.setProperty("webdriver.firefox.marionette", "C:\\selenium\\geckodriver.exe"); + webDriver = new FirefoxDriver(); + webDriver.manage().window().maximize(); + webDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); + webDriver.get(url); + } + + public void closeWindow() { + webDriver.close(); + } + + public String getTitle() { + return webDriver.getTitle(); + } + + public void getAboutBaeldungPage() { + closeOverlay(); + clickAboutLink(); + clickAboutUsLink(); + } + + private void closeOverlay() { + List webElementList = webDriver.findElements(By.tagName("a")); + try { + if (webElementList != null && !webElementList.isEmpty()) { + webElementList.stream().filter(webElement -> "Close".equalsIgnoreCase(webElement.getAttribute("title"))).findAny().orElseThrow(NoSuchElementException::new).click(); + } + } catch (NoSuchElementException exception) { + exception.printStackTrace(); + } + } + + private void clickAboutLink() { + webDriver.findElement(By.partialLinkText("About")).click(); + } + + private void clickAboutUsLink() { + webDriver.findElement(By.partialLinkText("About Baeldung.")).click(); + } + + public boolean isAuthorInformationAvailable() { + return webDriver.findElement(By.xpath("//*[contains(text(), 'Eugen – an engineer')]")).isDisplayed(); + } +} diff --git a/selenium-junit-testng/src/test/java/com/baeldung/selenium/junit/SeleniumWithJUnitLiveTest.java b/selenium-junit-testng/src/test/java/com/baeldung/selenium/junit/SeleniumWithJUnitLiveTest.java new file mode 100644 index 0000000000..f8d9a5dada --- /dev/null +++ b/selenium-junit-testng/src/test/java/com/baeldung/selenium/junit/SeleniumWithJUnitLiveTest.java @@ -0,0 +1,41 @@ +package test.java.com.baeldung.selenium.junit; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; +import main.java.com.baeldung.selenium.SeleniumExample; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class SeleniumWithJUnitLiveTest { + + private static SeleniumExample seleniumExample; + private String expecteTilteAboutBaeldungPage = "About Baeldung | Baeldung"; + + @BeforeClass + public static void setUp() { + seleniumExample = new SeleniumExample(); + } + + @AfterClass + public static void tearDown() { + seleniumExample.closeWindow(); + } + + @Test + public void whenAboutBaeldungIsLoaded_thenAboutEugenIsMentionedOnPage() { + try { + seleniumExample.getAboutBaeldungPage(); + String actualTitle = seleniumExample.getTitle(); + assertNotNull(actualTitle); + assertEquals(actualTitle, expecteTilteAboutBaeldungPage); + assertTrue(seleniumExample.isAuthorInformationAvailable()); + } catch (Exception exception) { + exception.printStackTrace(); + seleniumExample.closeWindow(); + } + } + +} diff --git a/selenium-junit-testng/src/test/java/com/baeldung/selenium/testng/SeleniumWithTestNGLiveTest.java b/selenium-junit-testng/src/test/java/com/baeldung/selenium/testng/SeleniumWithTestNGLiveTest.java new file mode 100644 index 0000000000..5ec9ade39f --- /dev/null +++ b/selenium-junit-testng/src/test/java/com/baeldung/selenium/testng/SeleniumWithTestNGLiveTest.java @@ -0,0 +1,40 @@ +package test.java.com.baeldung.selenium.testng; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; +import main.java.com.baeldung.selenium.SeleniumExample; + +import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.Test; + +public class SeleniumWithTestNGLiveTest { + + private SeleniumExample seleniumExample; + private String expecteTilteAboutBaeldungPage = "About Baeldung | Baeldung"; + + @BeforeSuite + public void setUp() { + seleniumExample = new SeleniumExample(); + } + + @AfterSuite + public void tearDown() { + seleniumExample.closeWindow(); + } + + @Test + public void whenAboutBaeldungIsLoaded_thenAboutEugenIsMentionedOnPage() { + try { + seleniumExample.getAboutBaeldungPage(); + String actualTitle = seleniumExample.getTitle(); + assertNotNull(actualTitle); + assertEquals(actualTitle, expecteTilteAboutBaeldungPage); + assertTrue(seleniumExample.isAuthorInformationAvailable()); + } catch (Exception exception) { + exception.printStackTrace(); + seleniumExample.closeWindow(); + } + } +} diff --git a/spring-akka/README.md b/spring-akka/README.md new file mode 100644 index 0000000000..0f1c013214 --- /dev/null +++ b/spring-akka/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Introduction to Spring with Akka](http://www.baeldung.com/akka-with-spring) diff --git a/spring-akka/pom.xml b/spring-akka/pom.xml new file mode 100644 index 0000000000..eb33ca4848 --- /dev/null +++ b/spring-akka/pom.xml @@ -0,0 +1,127 @@ + + 4.0.0 + com.baeldung + spring-akka + 0.1-SNAPSHOT + + spring-akka + + + + + org.springframework + spring-context + + + + com.typesafe.akka + akka-actor_2.11 + ${akka.version} + + + + org.springframework + spring-test + test + + + + junit + junit + ${junit.version} + test + + + + + + + + + + org.springframework + spring-framework-bom + ${spring.version} + pom + import + + + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + + 4.3.2.RELEASE + 2.4.8 + 4.12 + + 3.5.1 + 2.19.1 + + + + \ No newline at end of file diff --git a/spring-all/src/main/java/org/baeldung/akka/AppConfiguration.java b/spring-akka/src/main/java/org/baeldung/akka/AppConfiguration.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/akka/AppConfiguration.java rename to spring-akka/src/main/java/org/baeldung/akka/AppConfiguration.java diff --git a/spring-all/src/main/java/org/baeldung/akka/GreetingActor.java b/spring-akka/src/main/java/org/baeldung/akka/GreetingActor.java similarity index 88% rename from spring-all/src/main/java/org/baeldung/akka/GreetingActor.java rename to spring-akka/src/main/java/org/baeldung/akka/GreetingActor.java index 1a9386c769..6366c277a4 100644 --- a/spring-all/src/main/java/org/baeldung/akka/GreetingActor.java +++ b/spring-akka/src/main/java/org/baeldung/akka/GreetingActor.java @@ -1,13 +1,12 @@ package org.baeldung.akka; import akka.actor.UntypedActor; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; -import static org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_PROTOTYPE; - @Component -@Scope(SCOPE_PROTOTYPE) +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class GreetingActor extends UntypedActor { private GreetingService greetingService; diff --git a/spring-all/src/main/java/org/baeldung/akka/GreetingService.java b/spring-akka/src/main/java/org/baeldung/akka/GreetingService.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/akka/GreetingService.java rename to spring-akka/src/main/java/org/baeldung/akka/GreetingService.java diff --git a/spring-all/src/main/java/org/baeldung/akka/SpringActorProducer.java b/spring-akka/src/main/java/org/baeldung/akka/SpringActorProducer.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/akka/SpringActorProducer.java rename to spring-akka/src/main/java/org/baeldung/akka/SpringActorProducer.java diff --git a/spring-all/src/main/java/org/baeldung/akka/SpringExtension.java b/spring-akka/src/main/java/org/baeldung/akka/SpringExtension.java similarity index 99% rename from spring-all/src/main/java/org/baeldung/akka/SpringExtension.java rename to spring-akka/src/main/java/org/baeldung/akka/SpringExtension.java index 624e289812..aa5941c763 100644 --- a/spring-all/src/main/java/org/baeldung/akka/SpringExtension.java +++ b/spring-akka/src/main/java/org/baeldung/akka/SpringExtension.java @@ -29,5 +29,4 @@ public class SpringExtension extends AbstractExtensionId - 4.0.0 - com.baeldung - spring-all - 0.1-SNAPSHOT + + 4.0.0 + com.baeldung + spring-all + 0.1-SNAPSHOT - spring-all - war + spring-all + war - - org.springframework.boot - spring-boot-starter-parent - 1.3.6.RELEASE - + + org.springframework.boot + spring-boot-starter-parent + 1.3.6.RELEASE + - - - com.fasterxml.jackson.core - jackson-databind - + + + com.fasterxml.jackson.core + jackson-databind + - + - - org.springframework - spring-web - - - org.springframework - spring-webmvc - - - org.springframework - spring-orm - - - org.springframework - spring-context - + + org.springframework + spring-web + + + org.springframework + spring-webmvc + + + org.springframework + spring-orm + + + org.springframework + spring-context + - + - - org.springframework - spring-aspects - + + org.springframework + spring-aspects + - + - - org.hibernate - hibernate-core - ${hibernate.version} - - - org.javassist - javassist - - - mysql - mysql-connector-java - runtime - - - org.hsqldb - hsqldb - - - + + org.hibernate + hibernate-core + ${hibernate.version} + + + org.javassist + javassist + + + mysql + mysql-connector-java + runtime + + + org.hsqldb + hsqldb + - - org.hibernate - hibernate-validator - + - + + org.hibernate + hibernate-validator + - - javax.servlet - javax.servlet-api - provided - + - - javax.servlet - jstl - runtime - + + javax.servlet + javax.servlet-api + provided + - + + javax.servlet + jstl + runtime + - - com.typesafe.akka - akka-actor_2.11 - 2.4.8 - + - + + com.google.guava + guava + ${guava.version} + - - com.google.guava - guava - ${guava.version} - - - + - - org.slf4j - slf4j-api - - - ch.qos.logback - logback-classic - - - - org.slf4j - jcl-over-slf4j - - - - org.slf4j - log4j-over-slf4j - + + org.slf4j + slf4j-api + + + ch.qos.logback + logback-classic + + + + org.slf4j + jcl-over-slf4j + + + + org.slf4j + log4j-over-slf4j + - + - - org.springframework - spring-test - test - + + org.springframework + spring-test + test + - - junit - junit - test - + + junit + junit + test + - - org.hamcrest - hamcrest-core - test - - - org.hamcrest - hamcrest-library - test - + + org.assertj + assertj-core + 3.5.1 + test + - - org.mockito - mockito-core - test - + + org.hamcrest + hamcrest-core + test + + + org.hamcrest + hamcrest-library + test + - - org.easymock - easymock - 3.4 - test - + + org.mockito + mockito-core + test + - + + org.easymock + easymock + 3.4 + test + + + org.ehcache + ehcache + 3.1.3 + - + - + - - org.springframework - spring-framework-bom - ${org.springframework.version} - pom - import - + - - org.springframework - spring-core - ${org.springframework.version} - + + org.springframework + spring-framework-bom + ${org.springframework.version} + pom + import + - + + org.springframework + spring-core + ${org.springframework.version} + - + - - spring-all - - - src/main/resources - true - - + - + + spring-all + + + src/main/resources + true + + - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - + - - org.apache.maven.plugins - maven-war-plugin - - false - - + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + - - org.apache.maven.plugins - maven-surefire-plugin - - - - - - - - - + + org.apache.maven.plugins + maven-war-plugin + + false + + - - org.codehaus.cargo - cargo-maven2-plugin - ${cargo-maven2-plugin.version} - - true - - jetty8x - embedded - - - - - - - 8082 - - - - + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*IntegrationTest.java + + + + + + - + - + - - - 4.3.1.RELEASE - 4.0.4.RELEASE - 3.20.0-GA - 1.2 + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + + + 4.3.1.RELEASE + 4.0.4.RELEASE + 3.20.0-GA + 1.2 - - 4.3.11.Final - 5.1.38 + + 4.3.11.Final + 5.1.38 - - 1.7.13 - 1.1.3 + + 1.7.13 + 1.1.3 - - 5.2.2.Final + + 5.2.2.Final - - 19.0 - 3.4 + + 19.0 + 3.4 - - 1.3 - 4.12 - 1.10.19 + + 1.3 + 4.12 + 1.10.19 - 4.4.1 - 4.5 + 4.4.1 + 4.5 - 2.9.0 + 2.9.0 - - 3.5.1 - 2.6 - 2.19.1 - 2.7 - 1.4.18 + + 3.5.1 + 2.6 + 2.19.1 + 2.7 + 1.4.18 - + \ No newline at end of file diff --git a/spring-all/src/main/java/org/baeldung/async/AsyncComponent.java b/spring-all/src/main/java/org/baeldung/async/AsyncComponent.java index 2946ab0aa1..8503f75c8f 100644 --- a/spring-all/src/main/java/org/baeldung/async/AsyncComponent.java +++ b/spring-all/src/main/java/org/baeldung/async/AsyncComponent.java @@ -1,11 +1,11 @@ package org.baeldung.async; -import java.util.concurrent.Future; - import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.stereotype.Component; +import java.util.concurrent.Future; + @Component public class AsyncComponent { @@ -19,7 +19,7 @@ public class AsyncComponent { System.out.println("Execute method asynchronously " + Thread.currentThread().getName()); try { Thread.sleep(5000); - return new AsyncResult("hello world !!!!"); + return new AsyncResult<>("hello world !!!!"); } catch (final InterruptedException e) { } diff --git a/spring-all/src/main/java/org/baeldung/caching/example/AbstractService.java b/spring-all/src/main/java/org/baeldung/caching/example/AbstractService.java index 38b5a5a3ec..02b8c3c159 100644 --- a/spring-all/src/main/java/org/baeldung/caching/example/AbstractService.java +++ b/spring-all/src/main/java/org/baeldung/caching/example/AbstractService.java @@ -72,5 +72,5 @@ public abstract class AbstractService { public String getAddress5(final Customer customer) { return customer.getAddress(); } - + } diff --git a/spring-all/src/main/java/org/baeldung/controller/config/StudentControllerConfig.java b/spring-all/src/main/java/org/baeldung/controller/config/StudentControllerConfig.java new file mode 100644 index 0000000000..ec6cf19785 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/controller/config/StudentControllerConfig.java @@ -0,0 +1,31 @@ +package org.baeldung.controller.config; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; + +import org.springframework.web.WebApplicationInitializer; +import org.springframework.web.context.ContextLoaderListener; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import org.springframework.web.context.support.GenericWebApplicationContext; +import org.springframework.web.servlet.DispatcherServlet; + +public class StudentControllerConfig implements WebApplicationInitializer { + + @Override + public void onStartup(ServletContext sc) throws ServletException { + AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); + root.register(WebConfig.class); + + root.setServletContext(sc); + + // Manages the lifecycle of the root application context + sc.addListener(new ContextLoaderListener(root)); + + DispatcherServlet dv = new DispatcherServlet(new GenericWebApplicationContext()); + + ServletRegistration.Dynamic appServlet = sc.addServlet("test-mvc", dv); + appServlet.setLoadOnStartup(1); + appServlet.addMapping("/test/*"); + } +} diff --git a/spring-all/src/main/java/org/baeldung/controller/config/WebConfig.java b/spring-all/src/main/java/org/baeldung/controller/config/WebConfig.java new file mode 100644 index 0000000000..251a1affa1 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/controller/config/WebConfig.java @@ -0,0 +1,28 @@ +package org.baeldung.controller.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.view.InternalResourceViewResolver; + +@Configuration +@EnableWebMvc +@ComponentScan(basePackages = { "org.baeldung.controller.controller", "org.baeldung.controller.config" }) +public class WebConfig extends WebMvcConfigurerAdapter { + @Override + public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } + + @Bean + public ViewResolver viewResolver() { + InternalResourceViewResolver bean = new InternalResourceViewResolver(); + bean.setPrefix("/WEB-INF/"); + bean.setSuffix(".jsp"); + return bean; + } +} \ No newline at end of file diff --git a/spring-all/src/main/java/org/baeldung/controller/controller/RestController.java b/spring-all/src/main/java/org/baeldung/controller/controller/RestController.java index 95903bcc40..4b38b4dd34 100644 --- a/spring-all/src/main/java/org/baeldung/controller/controller/RestController.java +++ b/spring-all/src/main/java/org/baeldung/controller/controller/RestController.java @@ -7,15 +7,15 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.ResponseBody; @Controller -public class RestController{ +public class RestController { - @GetMapping(value="/student/{studentId}") - public @ResponseBody Student getTestData(@PathVariable Integer studentId) { - Student student = new Student(); - student.setName("Peter"); - student.setId(studentId); + @GetMapping(value = "/student/{studentId}") + public @ResponseBody Student getTestData(@PathVariable Integer studentId) { + Student student = new Student(); + student.setName("Peter"); + student.setId(studentId); - return student; + return student; - } + } } diff --git a/spring-all/src/main/java/org/baeldung/controller/student/Student.java b/spring-all/src/main/java/org/baeldung/controller/student/Student.java index ee706d7028..5f49e5ceb9 100644 --- a/spring-all/src/main/java/org/baeldung/controller/student/Student.java +++ b/spring-all/src/main/java/org/baeldung/controller/student/Student.java @@ -1,33 +1,33 @@ package org.baeldung.controller.student; public class Student { - private String name; - - private int id; + private String name; - public String getName() { - return name; - } + private int id; - public void setName(String name) { - this.name = name; - } + public String getName() { + return name; + } - public int getId() { - return id; - } + public void setName(String name) { + this.name = name; + } - public void setId(int id) { - this.id = id; - } - - @Override - public int hashCode(){ - return this.id; - } - - @Override - public boolean equals(Object obj){ - return this.name.equals(((Student)obj).getName()); - } + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + @Override + public int hashCode() { + return this.id; + } + + @Override + public boolean equals(Object obj) { + return this.name.equals(((Student) obj).getName()); + } } \ No newline at end of file diff --git a/spring-all/src/main/java/org/baeldung/ehcache/calculator/SquaredCalculator.java b/spring-all/src/main/java/org/baeldung/ehcache/calculator/SquaredCalculator.java new file mode 100755 index 0000000000..25957539df --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/ehcache/calculator/SquaredCalculator.java @@ -0,0 +1,24 @@ +package org.baeldung.ehcache.calculator; + +import org.baeldung.ehcache.config.CacheHelper; + +public class SquaredCalculator { + private CacheHelper cache; + + public int getSquareValueOfNumber(int input) { + if (cache.getSquareNumberCache().containsKey(input)) { + return cache.getSquareNumberCache().get(input); + } + + System.out.println("Calculating square value of " + input + " and caching result."); + + int squaredValue = (int) Math.pow(input, 2); + cache.getSquareNumberCache().put(input, squaredValue); + + return squaredValue; + } + + public void setCache(CacheHelper cache) { + this.cache = cache; + } +} diff --git a/spring-all/src/main/java/org/baeldung/ehcache/config/CacheHelper.java b/spring-all/src/main/java/org/baeldung/ehcache/config/CacheHelper.java new file mode 100755 index 0000000000..7f59ad8cfb --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/ehcache/config/CacheHelper.java @@ -0,0 +1,29 @@ +package org.baeldung.ehcache.config; + +import org.ehcache.Cache; +import org.ehcache.CacheManager; +import org.ehcache.config.builders.CacheConfigurationBuilder; +import org.ehcache.config.builders.CacheManagerBuilder; +import org.ehcache.config.builders.ResourcePoolsBuilder; + +public class CacheHelper { + + private CacheManager cacheManager; + private Cache squareNumberCache; + + public CacheHelper() { + cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build(); + cacheManager.init(); + + squareNumberCache = cacheManager.createCache("squaredNumber", CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, Integer.class, ResourcePoolsBuilder.heap(10))); + } + + public Cache getSquareNumberCache() { + return squareNumberCache; + } + + public Cache getSquareNumberCacheFromCacheManager() { + return cacheManager.getCache("squaredNumber", Integer.class, Integer.class); + } + +} diff --git a/spring-all/src/main/java/org/baeldung/profiles/DatasourceConfig.java b/spring-all/src/main/java/org/baeldung/profiles/DatasourceConfig.java index 80cb060c7e..8fde925fd8 100644 --- a/spring-all/src/main/java/org/baeldung/profiles/DatasourceConfig.java +++ b/spring-all/src/main/java/org/baeldung/profiles/DatasourceConfig.java @@ -1,5 +1,5 @@ package org.baeldung.profiles; public interface DatasourceConfig { - public void setup(); + void setup(); } diff --git a/spring-all/src/main/java/org/baeldung/properties/spring/PropertiesWithPlaceHolderConfigurer.java b/spring-all/src/main/java/org/baeldung/properties/spring/PropertiesWithPlaceHolderConfigurer.java index f96184a8a3..97d7fe0ffa 100644 --- a/spring-all/src/main/java/org/baeldung/properties/spring/PropertiesWithPlaceHolderConfigurer.java +++ b/spring-all/src/main/java/org/baeldung/properties/spring/PropertiesWithPlaceHolderConfigurer.java @@ -11,7 +11,6 @@ public class PropertiesWithPlaceHolderConfigurer { super(); } - @Bean public PropertyPlaceholderConfigurer propertyConfigurer() { final PropertyPlaceholderConfigurer props = new PropertyPlaceholderConfigurer(); diff --git a/spring-all/src/main/java/org/baeldung/scopes/HelloMessageGenerator.java b/spring-all/src/main/java/org/baeldung/scopes/HelloMessageGenerator.java index ae1c6157db..562069bc9a 100644 --- a/spring-all/src/main/java/org/baeldung/scopes/HelloMessageGenerator.java +++ b/spring-all/src/main/java/org/baeldung/scopes/HelloMessageGenerator.java @@ -2,14 +2,14 @@ package org.baeldung.scopes; public class HelloMessageGenerator { - private String message; + private String message; - public String getMessage() { - return message; - } + public String getMessage() { + return message; + } - public void setMessage(final String message) { - this.message = message; - } + public void setMessage(final String message) { + this.message = message; + } } diff --git a/spring-all/src/main/java/org/baeldung/scopes/Person.java b/spring-all/src/main/java/org/baeldung/scopes/Person.java index e6139c31dd..b070007a5c 100644 --- a/spring-all/src/main/java/org/baeldung/scopes/Person.java +++ b/spring-all/src/main/java/org/baeldung/scopes/Person.java @@ -1,27 +1,27 @@ package org.baeldung.scopes; public class Person { - private String name; - private int age; + private String name; + private int age; - public Person() { - } + public Person() { + } - public Person(final String name, final int age) { - this.name = name; - } + public Person(final String name, final int age) { + this.name = name; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public void setName(final String name) { - this.name = name; - } + public void setName(final String name) { + this.name = name; + } - @Override - public String toString() { - return "Person [name=" + name + "]"; - } + @Override + public String toString() { + return "Person [name=" + name + "]"; + } } diff --git a/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java b/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java index bf733b75f9..1e3d5f3b14 100644 --- a/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java +++ b/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java @@ -9,23 +9,23 @@ import org.springframework.web.bind.annotation.RequestMapping; @Controller public class ScopesController { - public static final Logger LOG = Logger.getLogger(ScopesController.class); + public static final Logger LOG = Logger.getLogger(ScopesController.class); - @Resource(name = "requestMessage") - HelloMessageGenerator requestMessage; + @Resource(name = "requestMessage") + HelloMessageGenerator requestMessage; - @Resource(name = "sessionMessage") - HelloMessageGenerator sessionMessage; + @Resource(name = "sessionMessage") + HelloMessageGenerator sessionMessage; - @RequestMapping("/scopes") - public String getScopes(final Model model) { - LOG.info("Request Message:" + requestMessage.getMessage()); - LOG.info("Session Message" + sessionMessage.getMessage()); - requestMessage.setMessage("Good morning!"); - sessionMessage.setMessage("Good afternoon!"); - model.addAttribute("requestMessage", requestMessage.getMessage()); - model.addAttribute("sessionMessage", sessionMessage.getMessage()); - return "scopesExample"; - } + @RequestMapping("/scopes") + public String getScopes(final Model model) { + LOG.info("Request Message:" + requestMessage.getMessage()); + LOG.info("Session Message" + sessionMessage.getMessage()); + requestMessage.setMessage("Good morning!"); + sessionMessage.setMessage("Good afternoon!"); + model.addAttribute("requestMessage", requestMessage.getMessage()); + model.addAttribute("sessionMessage", sessionMessage.getMessage()); + return "scopesExample"; + } } diff --git a/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java b/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java index 5a9b266388..a9bc298db3 100644 --- a/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java +++ b/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java @@ -16,42 +16,42 @@ import org.springframework.web.servlet.view.UrlBasedViewResolver; @ComponentScan("org.baeldung.scopes") @EnableWebMvc public class ScopesConfig { - @Bean - public UrlBasedViewResolver setupViewResolver() { - final UrlBasedViewResolver resolver = new UrlBasedViewResolver(); - resolver.setPrefix("/WEB-INF/view/"); - resolver.setSuffix(".jsp"); - resolver.setViewClass(JstlView.class); - return resolver; - } + @Bean + public UrlBasedViewResolver setupViewResolver() { + final UrlBasedViewResolver resolver = new UrlBasedViewResolver(); + resolver.setPrefix("/WEB-INF/view/"); + resolver.setSuffix(".jsp"); + resolver.setViewClass(JstlView.class); + return resolver; + } - @Bean - @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) - public HelloMessageGenerator requestMessage() { - return new HelloMessageGenerator(); - } + @Bean + @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) + public HelloMessageGenerator requestMessage() { + return new HelloMessageGenerator(); + } - @Bean - @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) - public HelloMessageGenerator sessionMessage() { - return new HelloMessageGenerator(); - } + @Bean + @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) + public HelloMessageGenerator sessionMessage() { + return new HelloMessageGenerator(); + } - @Bean - @Scope(value = WebApplicationContext.SCOPE_GLOBAL_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) - public HelloMessageGenerator globalSessionMessage() { - return new HelloMessageGenerator(); - } + @Bean + @Scope(value = WebApplicationContext.SCOPE_GLOBAL_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) + public HelloMessageGenerator globalSessionMessage() { + return new HelloMessageGenerator(); + } - @Bean - @Scope("prototype") - public Person personPrototype() { - return new Person(); - } + @Bean + @Scope("prototype") + public Person personPrototype() { + return new Person(); + } - @Bean - @Scope("singleton") - public Person personSingleton() { - return new Person(); - } + @Bean + @Scope("singleton") + public Person personSingleton() { + return new Person(); + } } diff --git a/spring-all/src/main/java/org/baeldung/spring43/cache/Foo.java b/spring-all/src/main/java/org/baeldung/spring43/cache/Foo.java index 4abd3cc813..ce34adf6c1 100644 --- a/spring-all/src/main/java/org/baeldung/spring43/cache/Foo.java +++ b/spring-all/src/main/java/org/baeldung/spring43/cache/Foo.java @@ -11,7 +11,6 @@ public class Foo { private static final AtomicInteger instanceCount = new AtomicInteger(0); - private final int instanceNum; public Foo() { diff --git a/spring-all/src/main/java/org/baeldung/startup/AllStrategiesExampleBean.java b/spring-all/src/main/java/org/baeldung/startup/AllStrategiesExampleBean.java new file mode 100644 index 0000000000..d4334437f7 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/startup/AllStrategiesExampleBean.java @@ -0,0 +1,33 @@ +package org.baeldung.startup; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +@Component +@Scope(value = "prototype") +public class AllStrategiesExampleBean implements InitializingBean { + + private static final Logger LOG = Logger.getLogger(AllStrategiesExampleBean.class); + + public AllStrategiesExampleBean() { + LOG.info("Constructor"); + } + + @Override + public void afterPropertiesSet() throws Exception { + LOG.info("InitializingBean"); + } + + @PostConstruct + public void postConstruct() { + LOG.info("PostConstruct"); + } + + public void init() { + LOG.info("init-method"); + } +} diff --git a/spring-all/src/main/java/org/baeldung/startup/EventListenerExampleBean.java b/spring-all/src/main/java/org/baeldung/startup/EventListenerExampleBean.java new file mode 100644 index 0000000000..e9cd1a159d --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/startup/EventListenerExampleBean.java @@ -0,0 +1,19 @@ +package org.baeldung.startup; + +import org.apache.log4j.Logger; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +@Component +public class EventListenerExampleBean { + private static final Logger LOG = Logger.getLogger(EventListenerExampleBean.class); + + public static int counter; + + @EventListener + public void onApplicationEvent(ContextRefreshedEvent event) { + LOG.info("Increment counter"); + counter++; + } +} diff --git a/spring-all/src/main/java/org/baeldung/startup/InitMethodExampleBean.java b/spring-all/src/main/java/org/baeldung/startup/InitMethodExampleBean.java new file mode 100644 index 0000000000..cea6b026d6 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/startup/InitMethodExampleBean.java @@ -0,0 +1,23 @@ +package org.baeldung.startup; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import java.util.Arrays; + +@Component +@Scope(value = "prototype") +public class InitMethodExampleBean { + + private static final Logger LOG = Logger.getLogger(InitMethodExampleBean.class); + + @Autowired + private Environment environment; + + public void init() { + LOG.info(Arrays.asList(environment.getDefaultProfiles())); + } +} diff --git a/spring-all/src/main/java/org/baeldung/startup/InitializingBeanExampleBean.java b/spring-all/src/main/java/org/baeldung/startup/InitializingBeanExampleBean.java new file mode 100644 index 0000000000..33b14864f3 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/startup/InitializingBeanExampleBean.java @@ -0,0 +1,25 @@ +package org.baeldung.startup; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import java.util.Arrays; + +@Component +@Scope(value = "prototype") +public class InitializingBeanExampleBean implements InitializingBean { + + private static final Logger LOG = Logger.getLogger(InitializingBeanExampleBean.class); + + @Autowired + private Environment environment; + + @Override + public void afterPropertiesSet() throws Exception { + LOG.info(Arrays.asList(environment.getDefaultProfiles())); + } +} diff --git a/spring-all/src/main/java/org/baeldung/startup/InvalidInitExampleBean.java b/spring-all/src/main/java/org/baeldung/startup/InvalidInitExampleBean.java new file mode 100644 index 0000000000..0b9c6f0c7d --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/startup/InvalidInitExampleBean.java @@ -0,0 +1,18 @@ +package org.baeldung.startup; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +@Component +@Scope("prototype") +public class InvalidInitExampleBean { + + @Autowired + private Environment environment; + + public InvalidInitExampleBean() { + environment.getActiveProfiles(); + } +} diff --git a/spring-all/src/main/java/org/baeldung/startup/LogicInConstructorExampleBean.java b/spring-all/src/main/java/org/baeldung/startup/LogicInConstructorExampleBean.java new file mode 100644 index 0000000000..2a7b3e26c7 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/startup/LogicInConstructorExampleBean.java @@ -0,0 +1,25 @@ +package org.baeldung.startup; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import java.util.Arrays; + +@Component +@Scope(value = "prototype") +public class LogicInConstructorExampleBean { + + private static final Logger LOG = Logger.getLogger(LogicInConstructorExampleBean.class); + + private final Environment environment; + + @Autowired + public LogicInConstructorExampleBean(Environment environment) { + this.environment = environment; + + LOG.info(Arrays.asList(environment.getDefaultProfiles())); + } +} diff --git a/spring-all/src/main/java/org/baeldung/startup/PostConstructExampleBean.java b/spring-all/src/main/java/org/baeldung/startup/PostConstructExampleBean.java new file mode 100644 index 0000000000..4cabaad4df --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/startup/PostConstructExampleBean.java @@ -0,0 +1,25 @@ +package org.baeldung.startup; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.Arrays; + +@Component +@Scope(value = "prototype") +public class PostConstructExampleBean { + + private static final Logger LOG = Logger.getLogger(PostConstructExampleBean.class); + + @Autowired + private Environment environment; + + @PostConstruct + public void init() { + LOG.info(Arrays.asList(environment.getDefaultProfiles())); + } +} diff --git a/spring-all/src/main/java/org/baeldung/startup/SpringStartupConfig.java b/spring-all/src/main/java/org/baeldung/startup/SpringStartupConfig.java new file mode 100644 index 0000000000..12854e1be5 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/startup/SpringStartupConfig.java @@ -0,0 +1,9 @@ +package org.baeldung.startup; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan("org.baeldung.startup") +public class SpringStartupConfig { +} \ No newline at end of file diff --git a/spring-all/src/main/java/org/baeldung/startup/StartupApplicationListenerExample.java b/spring-all/src/main/java/org/baeldung/startup/StartupApplicationListenerExample.java new file mode 100644 index 0000000000..32a63f0c1a --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/startup/StartupApplicationListenerExample.java @@ -0,0 +1,20 @@ +package org.baeldung.startup; + +import org.apache.log4j.Logger; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.stereotype.Component; + +@Component +public class StartupApplicationListenerExample implements ApplicationListener { + + private static final Logger LOG = Logger.getLogger(StartupApplicationListenerExample.class); + + public static int counter; + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + LOG.info("Increment counter"); + counter++; + } +} diff --git a/spring-all/src/main/resources/startupConfig.xml b/spring-all/src/main/resources/startupConfig.xml new file mode 100644 index 0000000000..8226665a90 --- /dev/null +++ b/spring-all/src/main/resources/startupConfig.xml @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/spring-all/src/main/webapp/WEB-INF/web.xml b/spring-all/src/main/webapp/WEB-INF/web.xml index 4e0e7a231c..3ac9e9ed8c 100644 --- a/spring-all/src/main/webapp/WEB-INF/web.xml +++ b/spring-all/src/main/webapp/WEB-INF/web.xml @@ -9,11 +9,11 @@ org.springframework.web.servlet.DispatcherServlet - 1 contextConfigLocation /WEB-INF/test-mvc.xml + 1 diff --git a/spring-all/src/test/java/org/baeldung/async/AsyncAnnotationExampleTest.java b/spring-all/src/test/java/org/baeldung/async/AsyncAnnotationExampleIntegrationTest.java similarity index 97% rename from spring-all/src/test/java/org/baeldung/async/AsyncAnnotationExampleTest.java rename to spring-all/src/test/java/org/baeldung/async/AsyncAnnotationExampleIntegrationTest.java index 2f41766cb6..0c010cf732 100644 --- a/spring-all/src/test/java/org/baeldung/async/AsyncAnnotationExampleTest.java +++ b/spring-all/src/test/java/org/baeldung/async/AsyncAnnotationExampleIntegrationTest.java @@ -13,7 +13,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { SpringAsyncConfig.class }, loader = AnnotationConfigContextLoader.class) -public class AsyncAnnotationExampleTest { +public class AsyncAnnotationExampleIntegrationTest { @Autowired private AsyncComponent asyncAnnotationExample; diff --git a/spring-all/src/test/java/org/baeldung/async/AsyncWithXMLTest.java b/spring-all/src/test/java/org/baeldung/async/AsyncWithXMLIntegrationTest.java similarity index 95% rename from spring-all/src/test/java/org/baeldung/async/AsyncWithXMLTest.java rename to spring-all/src/test/java/org/baeldung/async/AsyncWithXMLIntegrationTest.java index b91666261c..ffaa653a9a 100644 --- a/spring-all/src/test/java/org/baeldung/async/AsyncWithXMLTest.java +++ b/spring-all/src/test/java/org/baeldung/async/AsyncWithXMLIntegrationTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:springAsync-config.xml") -public class AsyncWithXMLTest { +public class AsyncWithXMLIntegrationTest { @Autowired private AsyncComponent asyncAnnotationExample; diff --git a/spring-all/src/test/java/org/baeldung/controller/ControllerAnnotationIntegrationTest.java b/spring-all/src/test/java/org/baeldung/controller/ControllerAnnotationIntegrationTest.java new file mode 100644 index 0000000000..82c8704360 --- /dev/null +++ b/spring-all/src/test/java/org/baeldung/controller/ControllerAnnotationIntegrationTest.java @@ -0,0 +1,79 @@ +package org.baeldung.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.baeldung.controller.config.WebConfig; +import org.baeldung.controller.student.Student; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.AnnotationConfigWebContextLoader; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.servlet.ModelAndView; + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(classes = { WebConfig.class }, loader = AnnotationConfigWebContextLoader.class) +public class ControllerAnnotationIntegrationTest { + + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext wac; + + private Student selectedStudent; + + @Before + public void setUp() { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + + selectedStudent = new Student(); + selectedStudent.setId(1); + selectedStudent.setName("Peter"); + } + + @Test + public void testTestController() throws Exception { + + ModelAndView mv = this.mockMvc.perform(MockMvcRequestBuilders.get("/test/")).andReturn().getModelAndView(); + + // validate modal data + Assert.assertSame(mv.getModelMap().get("data").toString(), "Welcome home man"); + + // validate view name + Assert.assertSame(mv.getViewName(), "welcome"); + } + + @Test + public void testRestController() throws Exception { + + String responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/student/{studentId}", 1)).andReturn().getResponse().getContentAsString(); + + ObjectMapper reader = new ObjectMapper(); + + Student studentDetails = reader.readValue(responseBody, Student.class); + + Assert.assertEquals(selectedStudent, studentDetails); + + } + + @Test + public void testRestAnnotatedController() throws Exception { + + String responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/annotated/student/{studentId}", 1)).andReturn().getResponse().getContentAsString(); + + ObjectMapper reader = new ObjectMapper(); + + Student studentDetails = reader.readValue(responseBody, Student.class); + + Assert.assertEquals(selectedStudent, studentDetails); + } + +} diff --git a/spring-all/src/test/java/org/baeldung/controller/ControllerTest.java b/spring-all/src/test/java/org/baeldung/controller/ControllerIntegrationTest.java similarity index 85% rename from spring-all/src/test/java/org/baeldung/controller/ControllerTest.java rename to spring-all/src/test/java/org/baeldung/controller/ControllerIntegrationTest.java index f5e41cd5a2..8e8a021530 100644 --- a/spring-all/src/test/java/org/baeldung/controller/ControllerTest.java +++ b/spring-all/src/test/java/org/baeldung/controller/ControllerIntegrationTest.java @@ -19,8 +19,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration -@ContextConfiguration({"classpath:test-mvc.xml"}) -public class ControllerTest { +@ContextConfiguration({ "classpath:test-mvc.xml" }) +public class ControllerIntegrationTest { private MockMvc mockMvc; @@ -41,9 +41,7 @@ public class ControllerTest { @Test public void testTestController() throws Exception { - ModelAndView mv = this.mockMvc.perform(MockMvcRequestBuilders.get("/test/")) - .andReturn() - .getModelAndView(); + ModelAndView mv = this.mockMvc.perform(MockMvcRequestBuilders.get("/test/")).andReturn().getModelAndView(); // validate modal data Assert.assertSame(mv.getModelMap().get("data").toString(), "Welcome home man"); @@ -55,9 +53,7 @@ public class ControllerTest { @Test public void testRestController() throws Exception { - String responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/student/{studentId}", 1)) - .andReturn().getResponse() - .getContentAsString(); + String responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/student/{studentId}", 1)).andReturn().getResponse().getContentAsString(); ObjectMapper reader = new ObjectMapper(); @@ -70,9 +66,7 @@ public class ControllerTest { @Test public void testRestAnnotatedController() throws Exception { - String responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/annotated/student/{studentId}", 1)) - .andReturn().getResponse() - .getContentAsString(); + String responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/annotated/student/{studentId}", 1)).andReturn().getResponse().getContentAsString(); ObjectMapper reader = new ObjectMapper(); diff --git a/spring-all/src/test/java/org/baeldung/customannotation/DataAccessAnnotationTest.java b/spring-all/src/test/java/org/baeldung/customannotation/DataAccessAnnotationIntegrationTest.java similarity index 97% rename from spring-all/src/test/java/org/baeldung/customannotation/DataAccessAnnotationTest.java rename to spring-all/src/test/java/org/baeldung/customannotation/DataAccessAnnotationIntegrationTest.java index ec0d46876e..ae3d53fb9b 100644 --- a/spring-all/src/test/java/org/baeldung/customannotation/DataAccessAnnotationTest.java +++ b/spring-all/src/test/java/org/baeldung/customannotation/DataAccessAnnotationIntegrationTest.java @@ -14,7 +14,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { CustomAnnotationConfiguration.class }) -public class DataAccessAnnotationTest { +public class DataAccessAnnotationIntegrationTest { @DataAccess(entity = Person.class) private GenericDAO personGenericDAO; diff --git a/spring-all/src/test/java/org/baeldung/customannotation/DataAccessFieldCallbackTest.java b/spring-all/src/test/java/org/baeldung/customannotation/DataAccessFieldCallbackIntegrationTest.java similarity index 97% rename from spring-all/src/test/java/org/baeldung/customannotation/DataAccessFieldCallbackTest.java rename to spring-all/src/test/java/org/baeldung/customannotation/DataAccessFieldCallbackIntegrationTest.java index e47d03c961..bab2574cd2 100644 --- a/spring-all/src/test/java/org/baeldung/customannotation/DataAccessFieldCallbackTest.java +++ b/spring-all/src/test/java/org/baeldung/customannotation/DataAccessFieldCallbackIntegrationTest.java @@ -17,7 +17,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { CustomAnnotationConfiguration.class }) -public class DataAccessFieldCallbackTest { +public class DataAccessFieldCallbackIntegrationTest { @Autowired private ConfigurableListableBeanFactory configurableListableBeanFactory; diff --git a/spring-all/src/test/java/org/baeldung/ehcache/SquareCalculatorTest.java b/spring-all/src/test/java/org/baeldung/ehcache/SquareCalculatorTest.java new file mode 100644 index 0000000000..ab7aebf7a1 --- /dev/null +++ b/spring-all/src/test/java/org/baeldung/ehcache/SquareCalculatorTest.java @@ -0,0 +1,43 @@ +package org.baeldung.ehcache; + +import org.baeldung.ehcache.calculator.SquaredCalculator; +import org.baeldung.ehcache.config.CacheHelper; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class SquareCalculatorTest { + private SquaredCalculator squaredCalculator = new SquaredCalculator(); + private CacheHelper cacheHelper = new CacheHelper(); + + @Before + public void setup() { + squaredCalculator.setCache(cacheHelper); + } + + @Test + public void whenCalculatingSquareValueOnce_thenCacheDontHaveValues() { + for (int i = 10; i < 15; i++) { + assertFalse(cacheHelper.getSquareNumberCache().containsKey(i)); + System.out.println("Square value of " + i + " is: " + + squaredCalculator.getSquareValueOfNumber(i) + "\n"); + } + } + + @Test + public void whenCalculatingSquareValueAgain_thenCacheHasAllValues() { + for (int i = 10; i < 15; i++) { + assertFalse(cacheHelper.getSquareNumberCache().containsKey(i)); + System.out.println("Square value of " + i + " is: " + + squaredCalculator.getSquareValueOfNumber(i) + "\n"); + } + + for (int i = 10; i < 15; i++) { + assertTrue(cacheHelper.getSquareNumberCache().containsKey(i)); + System.out.println("Square value of " + i + " is: " + + squaredCalculator.getSquareValueOfNumber(i) + "\n"); + } + } +} diff --git a/spring-all/src/test/java/org/baeldung/jdbc/EmployeeDAOTest.java b/spring-all/src/test/java/org/baeldung/jdbc/EmployeeDAOIntegrationTest.java similarity index 99% rename from spring-all/src/test/java/org/baeldung/jdbc/EmployeeDAOTest.java rename to spring-all/src/test/java/org/baeldung/jdbc/EmployeeDAOIntegrationTest.java index d544409254..4a92aa838f 100644 --- a/spring-all/src/test/java/org/baeldung/jdbc/EmployeeDAOTest.java +++ b/spring-all/src/test/java/org/baeldung/jdbc/EmployeeDAOIntegrationTest.java @@ -15,7 +15,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { SpringJdbcConfig.class }, loader = AnnotationConfigContextLoader.class) -public class EmployeeDAOTest { +public class EmployeeDAOIntegrationTest { @Autowired private EmployeeDAO employeeDao; diff --git a/spring-all/src/test/java/org/baeldung/profiles/DevProfileWithAnnotationTest.java b/spring-all/src/test/java/org/baeldung/profiles/DevProfileWithAnnotationIntegrationTest.java similarity index 93% rename from spring-all/src/test/java/org/baeldung/profiles/DevProfileWithAnnotationTest.java rename to spring-all/src/test/java/org/baeldung/profiles/DevProfileWithAnnotationIntegrationTest.java index 2b65928da8..cf5ca132e6 100644 --- a/spring-all/src/test/java/org/baeldung/profiles/DevProfileWithAnnotationTest.java +++ b/spring-all/src/test/java/org/baeldung/profiles/DevProfileWithAnnotationIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; @RunWith(SpringJUnit4ClassRunner.class) @ActiveProfiles("dev") @ContextConfiguration(classes = { SpringProfilesConfig.class }, loader = AnnotationConfigContextLoader.class) -public class DevProfileWithAnnotationTest { +public class DevProfileWithAnnotationIntegrationTest { @Autowired DatasourceConfig datasourceConfig; diff --git a/spring-all/src/test/java/org/baeldung/profiles/ProductionProfileWithAnnotationTest.java b/spring-all/src/test/java/org/baeldung/profiles/ProductionProfileWithAnnotationIntegrationTest.java similarity index 94% rename from spring-all/src/test/java/org/baeldung/profiles/ProductionProfileWithAnnotationTest.java rename to spring-all/src/test/java/org/baeldung/profiles/ProductionProfileWithAnnotationIntegrationTest.java index 551636bd31..5bacaef07b 100644 --- a/spring-all/src/test/java/org/baeldung/profiles/ProductionProfileWithAnnotationTest.java +++ b/spring-all/src/test/java/org/baeldung/profiles/ProductionProfileWithAnnotationIntegrationTest.java @@ -13,7 +13,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; @RunWith(SpringJUnit4ClassRunner.class) @ActiveProfiles("production") @ContextConfiguration(classes = { SpringProfilesConfig.class }, loader = AnnotationConfigContextLoader.class) -public class ProductionProfileWithAnnotationTest { +public class ProductionProfileWithAnnotationIntegrationTest { @Autowired DatasourceConfig datasourceConfig; diff --git a/spring-all/src/test/java/org/baeldung/properties/parentchild/ParentChildPropertyPlaceHolderPropertiesTest.java b/spring-all/src/test/java/org/baeldung/properties/parentchild/ParentChildPropertyPlaceHolderPropertiesIntegrationTest.java similarity index 96% rename from spring-all/src/test/java/org/baeldung/properties/parentchild/ParentChildPropertyPlaceHolderPropertiesTest.java rename to spring-all/src/test/java/org/baeldung/properties/parentchild/ParentChildPropertyPlaceHolderPropertiesIntegrationTest.java index 92af3f52f0..e0eccc978a 100644 --- a/spring-all/src/test/java/org/baeldung/properties/parentchild/ParentChildPropertyPlaceHolderPropertiesTest.java +++ b/spring-all/src/test/java/org/baeldung/properties/parentchild/ParentChildPropertyPlaceHolderPropertiesIntegrationTest.java @@ -18,7 +18,7 @@ import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextHierarchy({ @ContextConfiguration(classes = ParentConfig2.class), @ContextConfiguration(classes = ChildConfig2.class) }) -public class ParentChildPropertyPlaceHolderPropertiesTest { +public class ParentChildPropertyPlaceHolderPropertiesIntegrationTest { @Autowired private WebApplicationContext wac; diff --git a/spring-all/src/test/java/org/baeldung/properties/parentchild/ParentChildPropertySourcePropertiesTest.java b/spring-all/src/test/java/org/baeldung/properties/parentchild/ParentChildPropertySourcePropertiesIntegrationTest.java similarity index 96% rename from spring-all/src/test/java/org/baeldung/properties/parentchild/ParentChildPropertySourcePropertiesTest.java rename to spring-all/src/test/java/org/baeldung/properties/parentchild/ParentChildPropertySourcePropertiesIntegrationTest.java index 3ffd490c87..e9990523a7 100644 --- a/spring-all/src/test/java/org/baeldung/properties/parentchild/ParentChildPropertySourcePropertiesTest.java +++ b/spring-all/src/test/java/org/baeldung/properties/parentchild/ParentChildPropertySourcePropertiesIntegrationTest.java @@ -18,7 +18,7 @@ import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextHierarchy({ @ContextConfiguration(classes = ParentConfig.class), @ContextConfiguration(classes = ChildConfig.class) }) -public class ParentChildPropertySourcePropertiesTest { +public class ParentChildPropertySourcePropertiesIntegrationTest { @Autowired private WebApplicationContext wac; diff --git a/spring-all/src/test/java/org/baeldung/scheduling/ScheduledAnnotationExampleTest.java b/spring-all/src/test/java/org/baeldung/scheduling/ScheduledAnnotationExampleIntegrationTest.java similarity index 90% rename from spring-all/src/test/java/org/baeldung/scheduling/ScheduledAnnotationExampleTest.java rename to spring-all/src/test/java/org/baeldung/scheduling/ScheduledAnnotationExampleIntegrationTest.java index 9317c7bb7f..c5ca78aaa1 100644 --- a/spring-all/src/test/java/org/baeldung/scheduling/ScheduledAnnotationExampleTest.java +++ b/spring-all/src/test/java/org/baeldung/scheduling/ScheduledAnnotationExampleIntegrationTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { SpringSchedulingConfig.class }, loader = AnnotationConfigContextLoader.class) -public class ScheduledAnnotationExampleTest { +public class ScheduledAnnotationExampleIntegrationTest { @Test public void testScheduledAnnotation() throws InterruptedException { diff --git a/spring-all/src/test/java/org/baeldung/scheduling/SchedulingWithXmlConfigTest.java b/spring-all/src/test/java/org/baeldung/scheduling/SchedulingWithXmlConfigIntegrationTest.java similarity index 89% rename from spring-all/src/test/java/org/baeldung/scheduling/SchedulingWithXmlConfigTest.java rename to spring-all/src/test/java/org/baeldung/scheduling/SchedulingWithXmlConfigIntegrationTest.java index 0fca4d21c8..08df73f8fd 100644 --- a/spring-all/src/test/java/org/baeldung/scheduling/SchedulingWithXmlConfigTest.java +++ b/spring-all/src/test/java/org/baeldung/scheduling/SchedulingWithXmlConfigIntegrationTest.java @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:springScheduled-config.xml") -public class SchedulingWithXmlConfigTest { +public class SchedulingWithXmlConfigIntegrationTest { @Test public void testXmlBasedScheduling() throws InterruptedException { diff --git a/spring-all/src/test/java/org/baeldung/scopes/ScopesTest.java b/spring-all/src/test/java/org/baeldung/scopes/ScopesTest.java index b1dd248c26..59b9e225ad 100644 --- a/spring-all/src/test/java/org/baeldung/scopes/ScopesTest.java +++ b/spring-all/src/test/java/org/baeldung/scopes/ScopesTest.java @@ -8,36 +8,36 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; public class ScopesTest { - private static final String NAME = "John Smith"; - private static final String NAME_OTHER = "Anna Jones"; + private static final String NAME = "John Smith"; + private static final String NAME_OTHER = "Anna Jones"; - @Test - public void testScopeSingleton() { - final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("scopes.xml"); + @Test + public void testScopeSingleton() { + final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("scopes.xml"); - final Person personSingletonA = (Person) applicationContext.getBean("personSingleton"); - final Person personSingletonB = (Person) applicationContext.getBean("personSingleton"); + final Person personSingletonA = (Person) applicationContext.getBean("personSingleton"); + final Person personSingletonB = (Person) applicationContext.getBean("personSingleton"); - personSingletonA.setName(NAME); - Assert.assertEquals(NAME, personSingletonB.getName()); + personSingletonA.setName(NAME); + Assert.assertEquals(NAME, personSingletonB.getName()); - ((AbstractApplicationContext) applicationContext).close(); - } + ((AbstractApplicationContext) applicationContext).close(); + } - @Test - public void testScopePrototype() { - final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("scopes.xml"); + @Test + public void testScopePrototype() { + final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("scopes.xml"); - final Person personPrototypeA = (Person) applicationContext.getBean("personPrototype"); - final Person personPrototypeB = (Person) applicationContext.getBean("personPrototype"); + final Person personPrototypeA = (Person) applicationContext.getBean("personPrototype"); + final Person personPrototypeB = (Person) applicationContext.getBean("personPrototype"); - personPrototypeA.setName(NAME); - personPrototypeB.setName(NAME_OTHER); + personPrototypeA.setName(NAME); + personPrototypeB.setName(NAME_OTHER); - Assert.assertEquals(NAME, personPrototypeA.getName()); - Assert.assertEquals(NAME_OTHER, personPrototypeB.getName()); + Assert.assertEquals(NAME, personPrototypeA.getName()); + Assert.assertEquals(NAME_OTHER, personPrototypeB.getName()); - ((AbstractApplicationContext) applicationContext).close(); - } + ((AbstractApplicationContext) applicationContext).close(); + } } diff --git a/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationTest.java b/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationIntegrationTest.java similarity index 75% rename from spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationTest.java rename to spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationIntegrationTest.java index aa3acb113f..fff2716a64 100644 --- a/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationTest.java +++ b/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationIntegrationTest.java @@ -17,7 +17,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @ContextConfiguration(classes = AttributeAnnotationConfiguration.class) @WebAppConfiguration -public class AttributeAnnotationTest extends AbstractJUnit4SpringContextTests { +public class AttributeAnnotationIntegrationTest extends AbstractJUnit4SpringContextTests { private MockMvc mockMvc; @@ -26,18 +26,12 @@ public class AttributeAnnotationTest extends AbstractJUnit4SpringContextTests { @Before public void setup() { - this.mockMvc = MockMvcBuilders.webAppContextSetup(wac) - .build(); + this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); } @Test public void whenInterceptorAddsRequestAndSessionParams_thenParamsInjectedWithAttributesAnnotations() throws Exception { - String result = this.mockMvc.perform(get("/test") - .accept(MediaType.ALL)) - .andExpect(status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(); + String result = this.mockMvc.perform(get("/test").accept(MediaType.ALL)).andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); Assert.assertEquals("login = john, query = invoices", result); } diff --git a/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsTest.java b/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsIntegrationTest.java similarity index 92% rename from spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsTest.java rename to spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsIntegrationTest.java index bfd6e5047c..986932dafe 100644 --- a/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsTest.java +++ b/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import static org.junit.Assert.assertEquals; @ContextConfiguration(classes = CacheRefinementsConfiguration.class) -public class CacheRefinementsTest extends AbstractJUnit4SpringContextTests { +public class CacheRefinementsIntegrationTest extends AbstractJUnit4SpringContextTests { private ExecutorService executorService = Executors.newFixedThreadPool(10); diff --git a/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingTest.java b/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingIntegrationTest.java similarity index 80% rename from spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingTest.java rename to spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingIntegrationTest.java index 04fabbc834..d0af48cd0e 100644 --- a/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingTest.java +++ b/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingIntegrationTest.java @@ -17,7 +17,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @ContextConfiguration(classes = ComposedMappingConfiguration.class) @WebAppConfiguration -public class ComposedMappingTest extends AbstractJUnit4SpringContextTests { +public class ComposedMappingIntegrationTest extends AbstractJUnit4SpringContextTests { @Autowired private AppointmentService appointmentService; @@ -29,15 +29,12 @@ public class ComposedMappingTest extends AbstractJUnit4SpringContextTests { @Before public void setup() { - this.mockMvc = MockMvcBuilders.webAppContextSetup(wac) - .build(); + this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); } @Test public void whenRequestingMethodWithGetMapping_thenReceiving200Answer() throws Exception { - this.mockMvc.perform(get("/appointments") - .accept(MediaType.ALL)) - .andExpect(status().isOk()); + this.mockMvc.perform(get("/appointments").accept(MediaType.ALL)).andExpect(status().isOk()); verify(appointmentService); } diff --git a/spring-all/src/test/java/org/baeldung/spring43/ctor/ConfigurationConstructorInjectionTest.java b/spring-all/src/test/java/org/baeldung/spring43/ctor/ConfigurationConstructorInjectionIntegrationTest.java similarity index 71% rename from spring-all/src/test/java/org/baeldung/spring43/ctor/ConfigurationConstructorInjectionTest.java rename to spring-all/src/test/java/org/baeldung/spring43/ctor/ConfigurationConstructorInjectionIntegrationTest.java index 82caae15fe..871a985479 100644 --- a/spring-all/src/test/java/org/baeldung/spring43/ctor/ConfigurationConstructorInjectionTest.java +++ b/spring-all/src/test/java/org/baeldung/spring43/ctor/ConfigurationConstructorInjectionIntegrationTest.java @@ -7,8 +7,8 @@ import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import static org.junit.Assert.assertNotNull; -@ContextConfiguration(classes = {FooRepositoryConfiguration.class, FooServiceConfiguration.class}) -public class ConfigurationConstructorInjectionTest extends AbstractJUnit4SpringContextTests { +@ContextConfiguration(classes = { FooRepositoryConfiguration.class, FooServiceConfiguration.class }) +public class ConfigurationConstructorInjectionIntegrationTest extends AbstractJUnit4SpringContextTests { @Autowired public FooService fooService; diff --git a/spring-all/src/test/java/org/baeldung/spring43/ctor/ImplicitConstructorTest.java b/spring-all/src/test/java/org/baeldung/spring43/ctor/ImplicitConstructorIntegrationTest.java similarity index 86% rename from spring-all/src/test/java/org/baeldung/spring43/ctor/ImplicitConstructorTest.java rename to spring-all/src/test/java/org/baeldung/spring43/ctor/ImplicitConstructorIntegrationTest.java index be0cf77a62..83fa11294e 100644 --- a/spring-all/src/test/java/org/baeldung/spring43/ctor/ImplicitConstructorTest.java +++ b/spring-all/src/test/java/org/baeldung/spring43/ctor/ImplicitConstructorIntegrationTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import static org.junit.Assert.assertNotNull; @ContextConfiguration("classpath:implicit-ctor-context.xml") -public class ImplicitConstructorTest extends AbstractJUnit4SpringContextTests { +public class ImplicitConstructorIntegrationTest extends AbstractJUnit4SpringContextTests { @Autowired private FooService fooService; diff --git a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/DefaultMethodsInjectionTest.java b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/DefaultMethodsInjectionIntegrationTest.java similarity index 87% rename from spring-all/src/test/java/org/baeldung/spring43/defaultmethods/DefaultMethodsInjectionTest.java rename to spring-all/src/test/java/org/baeldung/spring43/defaultmethods/DefaultMethodsInjectionIntegrationTest.java index e29d89a679..956df44821 100644 --- a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/DefaultMethodsInjectionTest.java +++ b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/DefaultMethodsInjectionIntegrationTest.java @@ -10,7 +10,7 @@ import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import static org.junit.Assert.assertEquals; @ContextConfiguration("classpath:defaultmethods-context.xml") -public class DefaultMethodsInjectionTest extends AbstractJUnit4SpringContextTests { +public class DefaultMethodsInjectionIntegrationTest extends AbstractJUnit4SpringContextTests { @Autowired private IDateHolder dateHolder; diff --git a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTest.java b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalIntegrationTest.java similarity index 76% rename from spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTest.java rename to spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalIntegrationTest.java index 89c96ba1d4..b4ac7e8ccf 100644 --- a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTest.java +++ b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalIntegrationTest.java @@ -5,7 +5,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; @ContextConfiguration(classes = TransactionalTestConfiguration.class) -public class TransactionalTest extends AbstractTransactionalJUnit4SpringContextTests implements ITransactionalTest { +public class TransactionalIntegrationTest extends AbstractTransactionalJUnit4SpringContextTests implements ITransactionalTest { @Test public void whenDefaultMethodAnnotatedWithBeforeTransaction_thenDefaultMethodIsExecuted() { diff --git a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTestConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTestConfiguration.java index 946b19d00d..8a8cec3f86 100644 --- a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTestConfiguration.java +++ b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTestConfiguration.java @@ -1,6 +1,5 @@ package org.baeldung.spring43.defaultmethods; - import javax.sql.DataSource; import org.springframework.context.annotation.Bean; diff --git a/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderTest.java b/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderIntegrationTest.java similarity index 87% rename from spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderTest.java rename to spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderIntegrationTest.java index eeeb005f81..6d06bfdc2a 100644 --- a/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderTest.java +++ b/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderIntegrationTest.java @@ -8,7 +8,7 @@ import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import static org.junit.Assert.assertNotNull; @ContextConfiguration(classes = ObjectProviderConfiguration.class) -public class ObjectProviderTest extends AbstractJUnit4SpringContextTests { +public class ObjectProviderIntegrationTest extends AbstractJUnit4SpringContextTests { @Autowired private FooService fooService; diff --git a/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsTest.java b/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsIntegrationTest.java similarity index 58% rename from spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsTest.java rename to spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsIntegrationTest.java index b696760f68..69cce15029 100644 --- a/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsTest.java +++ b/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsIntegrationTest.java @@ -19,7 +19,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @ContextConfiguration(classes = ScopeAnnotationsConfiguration.class) @WebAppConfiguration -public class ScopeAnnotationsTest extends AbstractJUnit4SpringContextTests { +public class ScopeAnnotationsIntegrationTest extends AbstractJUnit4SpringContextTests { private MockMvc mockMvc; @@ -28,27 +28,16 @@ public class ScopeAnnotationsTest extends AbstractJUnit4SpringContextTests { @Before public void setup() { - this.mockMvc = MockMvcBuilders.webAppContextSetup(wac) - .build(); + this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); } @Test public void whenDifferentRequests_thenDifferentInstancesOfRequestScopedBeans() throws Exception { MockHttpSession session = new MockHttpSession(); - String requestScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/request") - .session(session) - .accept(MediaType.ALL)).andExpect(status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(); + String requestScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/request").session(session).accept(MediaType.ALL)).andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); - String requestScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/request") - .session(session) - .accept(MediaType.ALL)).andExpect(status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(); + String requestScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/request").session(session).accept(MediaType.ALL)).andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); assertNotEquals(requestScopedServiceInstanceNumber1, requestScopedServiceInstanceNumber2); } @@ -59,24 +48,9 @@ public class ScopeAnnotationsTest extends AbstractJUnit4SpringContextTests { MockHttpSession session1 = new MockHttpSession(); MockHttpSession session2 = new MockHttpSession(); - String sessionScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/session") - .session(session1) - .accept(MediaType.ALL)).andExpect(status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(); - String sessionScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/session") - .session(session1) - .accept(MediaType.ALL)).andExpect(status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(); - String sessionScopedServiceInstanceNumber3 = this.mockMvc.perform(get("/appointments/session") - .session(session2) - .accept(MediaType.ALL)).andExpect(status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(); + String sessionScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/session").session(session1).accept(MediaType.ALL)).andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + String sessionScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/session").session(session1).accept(MediaType.ALL)).andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + String sessionScopedServiceInstanceNumber3 = this.mockMvc.perform(get("/appointments/session").session(session2).accept(MediaType.ALL)).andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); assertEquals(sessionScopedServiceInstanceNumber1, sessionScopedServiceInstanceNumber2); @@ -90,18 +64,8 @@ public class ScopeAnnotationsTest extends AbstractJUnit4SpringContextTests { MockHttpSession session1 = new MockHttpSession(); MockHttpSession session2 = new MockHttpSession(); - String applicationScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/application") - .session(session1) - .accept(MediaType.ALL)).andExpect(status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(); - String applicationScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/application") - .session(session2) - .accept(MediaType.ALL)).andExpect(status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(); + String applicationScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/application").session(session1).accept(MediaType.ALL)).andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + String applicationScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/application").session(session2).accept(MediaType.ALL)).andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); assertEquals(applicationScopedServiceInstanceNumber1, applicationScopedServiceInstanceNumber2); diff --git a/spring-all/src/test/java/org/baeldung/springevents/asynchronous/AsynchronousCustomSpringEventsTest.java b/spring-all/src/test/java/org/baeldung/springevents/asynchronous/AsynchronousCustomSpringEventsIntegrationTest.java similarity index 93% rename from spring-all/src/test/java/org/baeldung/springevents/asynchronous/AsynchronousCustomSpringEventsTest.java rename to spring-all/src/test/java/org/baeldung/springevents/asynchronous/AsynchronousCustomSpringEventsIntegrationTest.java index 2b45ae4e68..e12baed7e0 100644 --- a/spring-all/src/test/java/org/baeldung/springevents/asynchronous/AsynchronousCustomSpringEventsTest.java +++ b/spring-all/src/test/java/org/baeldung/springevents/asynchronous/AsynchronousCustomSpringEventsIntegrationTest.java @@ -10,7 +10,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { AsynchronousSpringEventsConfig.class }, loader = AnnotationConfigContextLoader.class) -public class AsynchronousCustomSpringEventsTest { +public class AsynchronousCustomSpringEventsIntegrationTest { @Autowired private CustomSpringEventPublisher publisher; diff --git a/spring-all/src/test/java/org/baeldung/springevents/synchronous/ContextRefreshedListenerTest.java b/spring-all/src/test/java/org/baeldung/springevents/synchronous/ContextRefreshedListenerIntegrationTest.java similarity index 92% rename from spring-all/src/test/java/org/baeldung/springevents/synchronous/ContextRefreshedListenerTest.java rename to spring-all/src/test/java/org/baeldung/springevents/synchronous/ContextRefreshedListenerIntegrationTest.java index d971698e3f..ac8758bbf6 100644 --- a/spring-all/src/test/java/org/baeldung/springevents/synchronous/ContextRefreshedListenerTest.java +++ b/spring-all/src/test/java/org/baeldung/springevents/synchronous/ContextRefreshedListenerIntegrationTest.java @@ -9,7 +9,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { SynchronousSpringEventsConfig.class }, loader = AnnotationConfigContextLoader.class) -public class ContextRefreshedListenerTest { +public class ContextRefreshedListenerIntegrationTest { @Test public void testContextRefreshedListener() throws InterruptedException { diff --git a/spring-all/src/test/java/org/baeldung/springevents/synchronous/SynchronousCustomSpringEventsTest.java b/spring-all/src/test/java/org/baeldung/springevents/synchronous/SynchronousCustomSpringEventsIntegrationTest.java similarity index 93% rename from spring-all/src/test/java/org/baeldung/springevents/synchronous/SynchronousCustomSpringEventsTest.java rename to spring-all/src/test/java/org/baeldung/springevents/synchronous/SynchronousCustomSpringEventsIntegrationTest.java index b559ca9fc9..f9783f57dc 100644 --- a/spring-all/src/test/java/org/baeldung/springevents/synchronous/SynchronousCustomSpringEventsTest.java +++ b/spring-all/src/test/java/org/baeldung/springevents/synchronous/SynchronousCustomSpringEventsIntegrationTest.java @@ -9,7 +9,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { SynchronousSpringEventsConfig.class }, loader = AnnotationConfigContextLoader.class) -public class SynchronousCustomSpringEventsTest { +public class SynchronousCustomSpringEventsIntegrationTest { @Autowired private CustomSpringEventPublisher publisher; diff --git a/spring-all/src/test/java/org/baeldung/startup/SpringStartupIntegrationTest.java b/spring-all/src/test/java/org/baeldung/startup/SpringStartupIntegrationTest.java new file mode 100644 index 0000000000..6263482948 --- /dev/null +++ b/spring-all/src/test/java/org/baeldung/startup/SpringStartupIntegrationTest.java @@ -0,0 +1,44 @@ +package org.baeldung.startup; + +import org.assertj.core.api.Assertions; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +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 = { SpringStartupConfig.class }, loader = AnnotationConfigContextLoader.class) +public class SpringStartupIntegrationTest { + + @Autowired + private ApplicationContext ctx; + + @Test(expected = BeanCreationException.class) + public void whenInstantiating_shouldThrowBCE() throws Exception { + ctx.getBean(InvalidInitExampleBean.class); + } + + @Test + public void whenPostConstruct_shouldLogEnv() throws Exception { + ctx.getBean(PostConstructExampleBean.class); + } + + @Test + public void whenConstructorInjection_shouldLogEnv() throws Exception { + ctx.getBean(LogicInConstructorExampleBean.class); + } + + @Test + public void whenInitializingBean_shouldLogEnv() throws Exception { + ctx.getBean(InitializingBeanExampleBean.class); + } + + @Test + public void whenApplicationListener_shouldRunOnce() throws Exception { + Assertions.assertThat(StartupApplicationListenerExample.counter).isEqualTo(1); + } +} \ No newline at end of file diff --git a/spring-all/src/test/java/org/baeldung/startup/SpringStartupXMLConfigIntegrationTest.java b/spring-all/src/test/java/org/baeldung/startup/SpringStartupXMLConfigIntegrationTest.java new file mode 100644 index 0000000000..a46d24fa3b --- /dev/null +++ b/spring-all/src/test/java/org/baeldung/startup/SpringStartupXMLConfigIntegrationTest.java @@ -0,0 +1,26 @@ +package org.baeldung.startup; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:startupConfig.xml") +public class SpringStartupXMLConfigIntegrationTest { + + @Autowired + private ApplicationContext ctx; + + @Test + public void whenPostConstruct_shouldLogEnv() throws Exception { + ctx.getBean(InitMethodExampleBean.class); + } + + @Test + public void whenAllStrategies_shouldLogOrder() throws Exception { + ctx.getBean(AllStrategiesExampleBean.class); + } +} diff --git a/spring-apache-camel/src/main/java/com/baeldung/camel/file/FileProcessor.java b/spring-apache-camel/src/main/java/com/baeldung/camel/file/FileProcessor.java new file mode 100644 index 0000000000..1ea2cad188 --- /dev/null +++ b/spring-apache-camel/src/main/java/com/baeldung/camel/file/FileProcessor.java @@ -0,0 +1,20 @@ +package com.baeldung.camel.file; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; + +public class FileProcessor implements Processor { + + public void process(Exchange exchange) throws Exception { + String originalFileName = (String) exchange.getIn().getHeader(Exchange.FILE_NAME, String.class); + + Date date = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + String changedFileName = dateFormat.format(date) + originalFileName; + exchange.getIn().setHeader(Exchange.FILE_NAME, changedFileName); + } + +} diff --git a/spring-apache-camel/src/main/java/com/baeldung/camel/file/FileRouter.java b/spring-apache-camel/src/main/java/com/baeldung/camel/file/FileRouter.java new file mode 100644 index 0000000000..5216c9a595 --- /dev/null +++ b/spring-apache-camel/src/main/java/com/baeldung/camel/file/FileRouter.java @@ -0,0 +1,15 @@ +package com.baeldung.camel.file; + +import org.apache.camel.builder.RouteBuilder; + +public class FileRouter extends RouteBuilder { + + private static final String SOURCE_FOLDER = "src/test/source-folder"; + private static final String DESTINATION_FOLDER = "src/test/destination-folder"; + + @Override + public void configure() throws Exception { + from("file://" + SOURCE_FOLDER + "?delete=true").process(new FileProcessor()).to("file://" + DESTINATION_FOLDER); + } + +} diff --git a/spring-apache-camel/src/main/resources/camel-context-test.xml b/spring-apache-camel/src/main/resources/camel-context-test.xml new file mode 100644 index 0000000000..e6435db9e5 --- /dev/null +++ b/spring-apache-camel/src/main/resources/camel-context-test.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/spring-apache-camel/src/main/resources/camel-context.xml b/spring-apache-camel/src/main/resources/camel-context.xml index 0c10e0ecef..63ef406fdf 100644 --- a/spring-apache-camel/src/main/resources/camel-context.xml +++ b/spring-apache-camel/src/main/resources/camel-context.xml @@ -1,39 +1,39 @@ - + - + - - + + - - + + - - + + - - - ${body.toLowerCase()} - + + + ${body.toLowerCase()} + - - + + - - - .......... File content conversion completed .......... - - + + + .......... File content conversion completed .......... + + - + - + - + \ No newline at end of file diff --git a/spring-apache-camel/src/test/java/org/apache/camel/file/processor/FileProcessorTest.java b/spring-apache-camel/src/test/java/org/apache/camel/file/processor/FileProcessorTest.java new file mode 100644 index 0000000000..3d63f614e0 --- /dev/null +++ b/spring-apache-camel/src/test/java/org/apache/camel/file/processor/FileProcessorTest.java @@ -0,0 +1,68 @@ +package org.apache.camel.file.processor; + +import java.io.File; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.DefaultCamelContext; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import com.baeldung.camel.file.FileProcessor; + + +public class FileProcessorTest { + + private static final long DURATION_MILIS = 10000; + private static final String SOURCE_FOLDER = "src/test/source-folder"; + private static final String DESTINATION_FOLDER = "src/test/destination-folder"; + + @Before + public void setUp() throws Exception { + File sourceFolder = new File(SOURCE_FOLDER); + File destinationFolder = new File(DESTINATION_FOLDER); + + cleanFolder(sourceFolder); + cleanFolder(destinationFolder); + + sourceFolder.mkdirs(); + File file1 = new File(SOURCE_FOLDER + "/File1.txt"); + File file2 = new File(SOURCE_FOLDER + "/File2.txt"); + file1.createNewFile(); + file2.createNewFile(); + } + + private void cleanFolder(File folder) { + File[] files = folder.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isFile()) { + file.delete(); + } + } + } + } + + @Test + public void moveFolderContentJavaDSLTest() throws Exception { + final CamelContext camelContext = new DefaultCamelContext(); + camelContext.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + from("file://" + SOURCE_FOLDER + "?delete=true").process(new FileProcessor()).to("file://" + DESTINATION_FOLDER); + } + }); + camelContext.start(); + Thread.sleep(DURATION_MILIS); + camelContext.stop(); + } + + @Test + public void moveFolderContentSpringDSLTest() throws InterruptedException { + ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("camel-context-test.xml"); + Thread.sleep(DURATION_MILIS); + applicationContext.close(); + + } +} \ No newline at end of file diff --git a/spring-autowire/README.md b/spring-autowire/README.md new file mode 100644 index 0000000000..d5b8221b25 --- /dev/null +++ b/spring-autowire/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Guide to Spring @Autowired](http://www.baeldung.com/spring-autowire) diff --git a/spring-autowire/pom.xml b/spring-autowire/pom.xml index e28efdae61..fd03c77605 100644 --- a/spring-autowire/pom.xml +++ b/spring-autowire/pom.xml @@ -57,7 +57,48 @@ org.apache.maven.plugins maven-surefire-plugin ${maven-surefire-plugin.version} + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + diff --git a/spring-autowire/src/main/java/com/baeldung/autowire/sample/App.java b/spring-autowire/src/main/java/com/baeldung/autowire/sample/App.java index 725a9b8406..18ff11a49c 100644 --- a/spring-autowire/src/main/java/com/baeldung/autowire/sample/App.java +++ b/spring-autowire/src/main/java/com/baeldung/autowire/sample/App.java @@ -3,9 +3,9 @@ package com.baeldung.autowire.sample; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App { - public static void main(String[] args) { - AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); - FooService fooService = ctx.getBean(FooService.class); - fooService.doStuff(); - } + public static void main(String[] args) { + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); + FooService fooService = ctx.getBean(FooService.class); + fooService.doStuff(); + } } diff --git a/spring-autowire/src/main/java/com/baeldung/autowire/sample/BarFormatter.java b/spring-autowire/src/main/java/com/baeldung/autowire/sample/BarFormatter.java index fb704453fc..e67a376d25 100644 --- a/spring-autowire/src/main/java/com/baeldung/autowire/sample/BarFormatter.java +++ b/spring-autowire/src/main/java/com/baeldung/autowire/sample/BarFormatter.java @@ -9,5 +9,5 @@ public class BarFormatter implements Formatter { public String format() { return "bar"; } - + } diff --git a/spring-autowire/src/main/java/com/baeldung/autowire/sample/FooFormatter.java b/spring-autowire/src/main/java/com/baeldung/autowire/sample/FooFormatter.java index 73966e9e43..57f93a53d7 100644 --- a/spring-autowire/src/main/java/com/baeldung/autowire/sample/FooFormatter.java +++ b/spring-autowire/src/main/java/com/baeldung/autowire/sample/FooFormatter.java @@ -9,5 +9,5 @@ public class FooFormatter implements Formatter { public String format() { return "foo"; } - + } diff --git a/spring-autowire/src/main/java/com/baeldung/autowire/sample/FooService.java b/spring-autowire/src/main/java/com/baeldung/autowire/sample/FooService.java index eccea4351a..c55d93da11 100644 --- a/spring-autowire/src/main/java/com/baeldung/autowire/sample/FooService.java +++ b/spring-autowire/src/main/java/com/baeldung/autowire/sample/FooService.java @@ -5,13 +5,13 @@ import org.springframework.stereotype.Component; @Component public class FooService { - + @Autowired @FormatterType("Foo") private Formatter formatter; - - public String doStuff(){ + + public String doStuff() { return formatter.format(); } - + } diff --git a/spring-autowire/src/main/java/com/baeldung/autowire/sample/Formatter.java b/spring-autowire/src/main/java/com/baeldung/autowire/sample/Formatter.java index 83716d6e92..59d718050a 100644 --- a/spring-autowire/src/main/java/com/baeldung/autowire/sample/Formatter.java +++ b/spring-autowire/src/main/java/com/baeldung/autowire/sample/Formatter.java @@ -2,6 +2,6 @@ package com.baeldung.autowire.sample; public interface Formatter { - String format(); + String format(); } diff --git a/spring-autowire/src/main/java/com/baeldung/autowire/sample/FormatterType.java b/spring-autowire/src/main/java/com/baeldung/autowire/sample/FormatterType.java index 7ffc308c9a..f2961745b5 100644 --- a/spring-autowire/src/main/java/com/baeldung/autowire/sample/FormatterType.java +++ b/spring-autowire/src/main/java/com/baeldung/autowire/sample/FormatterType.java @@ -8,10 +8,10 @@ import java.lang.annotation.Target; import org.springframework.beans.factory.annotation.Qualifier; @Qualifier -@Target({ElementType.FIELD, ElementType.METHOD,ElementType.TYPE, ElementType.PARAMETER}) +@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) public @interface FormatterType { - + String value(); } diff --git a/spring-autowire/src/test/java/com/baeldung/autowire/sample/FooServiceTest.java b/spring-autowire/src/test/java/com/baeldung/autowire/sample/FooServiceIntegrationTest.java similarity index 74% rename from spring-autowire/src/test/java/com/baeldung/autowire/sample/FooServiceTest.java rename to spring-autowire/src/test/java/com/baeldung/autowire/sample/FooServiceIntegrationTest.java index 4607f527d9..34ba7902ca 100644 --- a/spring-autowire/src/test/java/com/baeldung/autowire/sample/FooServiceTest.java +++ b/spring-autowire/src/test/java/com/baeldung/autowire/sample/FooServiceIntegrationTest.java @@ -9,14 +9,14 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes=AppConfig.class, loader=AnnotationConfigContextLoader.class) -public class FooServiceTest { - +@ContextConfiguration(classes = AppConfig.class, loader = AnnotationConfigContextLoader.class) +public class FooServiceIntegrationTest { + @Autowired FooService fooService; - + @Test - public void whenFooFormatterType_thenReturnFoo(){ + public void whenFooFormatterType_thenReturnFoo() { Assert.assertEquals("foo", fooService.doStuff()); } } diff --git a/spring-boot/README.MD b/spring-boot/README.MD index 2a87b46021..1610d77e81 100644 --- a/spring-boot/README.MD +++ b/spring-boot/README.MD @@ -1,2 +1,7 @@ ###The Course The "REST With Spring" Classes: http://bit.ly/restwithspring + +###Relevant Articles: +- [Quick Guide to @RestClientTest in Spring Boot](http://www.baeldung.com/restclienttest-in-spring-boot) +- [Intro to Spring Boot Starters](http://www.baeldung.com/spring-boot-starters) +- [A Guide to Spring in Eclipse STS](http://www.baeldung.com/eclipse-sts-spring) diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index ada02a9965..a2555259b0 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -1,156 +1,223 @@ - 4.0.0 - com.baeldung - spring-boot - 0.0.1-SNAPSHOT - war - Spring Boot Actuator - This is simple boot application for Spring boot actuator test + 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 + spring-boot + 0.0.1-SNAPSHOT + war + Spring Boot Actuator + This is simple boot application for Spring boot actuator test - - - org.springframework.boot - spring-boot-starter-parent - 1.4.0.RC1 - - + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RC1 + + - - - org.baeldung.boot.DemoApplication - UTF-8 - 1.8 - - + + + org.baeldung.boot.DemoApplication + UTF-8 + 1.8 + 4.3.1.RELEASE + - - - org.springframework.boot - spring-boot-starter-web - + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-web + - - org.springframework.boot - spring-boot-starter-data-jpa - + + org.springframework.boot + spring-boot-starter-data-jpa + - - org.springframework.boot - spring-boot-starter-actuator - + + org.springframework.boot + spring-boot-starter-actuator + - - org.springframework.boot - spring-boot-starter-security - + + org.springframework.boot + spring-boot-starter-security + - - io.dropwizard.metrics - metrics-core - + + io.dropwizard.metrics + metrics-core + - - com.h2database - h2 - + + com.h2database + h2 + - - org.springframework.boot - spring-boot-starter-test - test - + + org.springframework.boot + spring-boot-starter-test + test + - - org.springframework.boot - spring-boot-starter - - - com.jayway.jsonpath - json-path - test - - - org.springframework.boot - spring-boot-starter-mail - - - org.subethamail - subethasmtp - 3.1.7 - test - - + + org.springframework.boot + spring-boot-starter + + + com.jayway.jsonpath + json-path + test + + + org.springframework.boot + spring-boot-starter-mail + + + org.subethamail + subethasmtp + 3.1.7 + test + + + + org.webjars + bootstrap + 3.3.7-1 + + + org.webjars + jquery + 3.1.1 + + - - spring-boot - - - src/main/resources - true - - + + spring-boot + + + src/main/resources + true + + - + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-war-plugin + - org.springframework.boot - spring-boot-maven-plugin + pl.project13.maven + git-commit-id-plugin + 2.2.1 org.apache.maven.plugins - maven-compiler-plugin + maven-surefire-plugin - 1.8 - 1.8 + + **/*IntegrationTest.java + **/*LiveTest.java + - - - org.apache.maven.plugins - maven-war-plugin - - + - + - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + diff --git a/webjars/src/main/java/com/baeldung/TestController.java b/spring-boot/src/main/java/com/baeldung/TestController.java similarity index 67% rename from webjars/src/main/java/com/baeldung/TestController.java rename to spring-boot/src/main/java/com/baeldung/TestController.java index 19a1c18c6b..0e28ca67f8 100644 --- a/webjars/src/main/java/com/baeldung/TestController.java +++ b/spring-boot/src/main/java/com/baeldung/TestController.java @@ -6,10 +6,10 @@ import org.springframework.web.bind.annotation.RequestMapping; @Controller public class TestController { - - @RequestMapping(value="/") - public String welcome(Model model){ - return "index"; - } + + @RequestMapping(value = "/") + public String welcome(Model model) { + return "index"; + } } diff --git a/webjars/src/main/java/com/baeldung/WebjarsdemoApplication.java b/spring-boot/src/main/java/com/baeldung/WebjarsdemoApplication.java similarity index 63% rename from webjars/src/main/java/com/baeldung/WebjarsdemoApplication.java rename to spring-boot/src/main/java/com/baeldung/WebjarsdemoApplication.java index c14dc682af..35490131c6 100644 --- a/webjars/src/main/java/com/baeldung/WebjarsdemoApplication.java +++ b/spring-boot/src/main/java/com/baeldung/WebjarsdemoApplication.java @@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class WebjarsdemoApplication { - public static void main(String[] args) { - SpringApplication.run(WebjarsdemoApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(WebjarsdemoApplication.class, args); + } } diff --git a/spring-boot/src/main/java/com/baeldung/git/CommitIdApplication.java b/spring-boot/src/main/java/com/baeldung/git/CommitIdApplication.java new file mode 100644 index 0000000000..cd696eae70 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/git/CommitIdApplication.java @@ -0,0 +1,23 @@ +package com.baeldung.git; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; +import org.springframework.core.io.ClassPathResource; + +@SpringBootApplication(scanBasePackages = { "com.baeldung.git" }) +public class CommitIdApplication { + public static void main(String[] args) { + SpringApplication.run(CommitIdApplication.class, args); + } + + @Bean + public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() { + PropertySourcesPlaceholderConfigurer c = new PropertySourcesPlaceholderConfigurer(); + c.setLocation(new ClassPathResource("git.properties")); + c.setIgnoreResourceNotFound(true); + c.setIgnoreUnresolvablePlaceholders(true); + return c; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/git/CommitInfoController.java b/spring-boot/src/main/java/com/baeldung/git/CommitInfoController.java new file mode 100644 index 0000000000..6d44e02ec2 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/git/CommitInfoController.java @@ -0,0 +1,30 @@ +package com.baeldung.git; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +@RestController +public class CommitInfoController { + + @Value("${git.commit.message.short}") + private String commitMessage; + + @Value("${git.branch}") + private String branch; + + @Value("${git.commit.id}") + private String commitId; + + @RequestMapping("/commitId") + public Map getCommitId() { + Map result = new HashMap<>(); + result.put("Commit message", commitMessage); + result.put("Commit branch", branch); + result.put("Commit id", commitId); + return result; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/git/README.md b/spring-boot/src/main/java/com/baeldung/git/README.md new file mode 100644 index 0000000000..7e6a597c28 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/git/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Injecting Git Information Into Spring](http://www.baeldung.com/spring-git-information) diff --git a/spring-boot/src/main/java/org/baeldung/main/SpringBootApplication.java b/spring-boot/src/main/java/org/baeldung/main/SpringBootApplication.java index 59955cc990..582d2d9e9c 100644 --- a/spring-boot/src/main/java/org/baeldung/main/SpringBootApplication.java +++ b/spring-boot/src/main/java/org/baeldung/main/SpringBootApplication.java @@ -1,8 +1,5 @@ package org.baeldung.main; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - import org.baeldung.common.error.SpringHelloServletRegistrationBean; import org.baeldung.common.resources.ExecutorServiceExitCodeGenerator; import org.baeldung.controller.servlet.HelloWorldServlet; @@ -17,6 +14,9 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + @RestController @EnableAutoConfiguration @ComponentScan({ "org.baeldung.common.error", "org.baeldung.common.error.controller", "org.baeldung.common.properties", "org.baeldung.common.resources", "org.baeldung.endpoints", "org.baeldung.service", "org.baeldung.monitor.jmx", "org.baeldung.service" }) @@ -55,28 +55,6 @@ public class SpringBootApplication { return bean; } - /* @Bean - public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() { - JettyEmbeddedServletContainerFactory jettyContainer = new JettyEmbeddedServletContainerFactory(); - jettyContainer.setPort(9000); - jettyContainer.setContextPath("/springbootapp"); - return jettyContainer; - } - - @Bean - public UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() { - UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory(); - factory.addBuilderCustomizers(new UndertowBuilderCustomizer() { - - @Override - public void customize(io.undertow.Undertow.Builde builder) { - builder.addHttpListener(8080, "0.0.0.0"); - } - - }); - return factory; - }*/ - @Bean @Autowired public ExecutorServiceExitCodeGenerator executorServiceExitCodeGenerator(ExecutorService executorService) { diff --git a/spring-boot/src/main/java/org/baeldung/session/exception/Application.java b/spring-boot/src/main/java/org/baeldung/session/exception/Application.java new file mode 100644 index 0000000000..23d741b98c --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/session/exception/Application.java @@ -0,0 +1,23 @@ +package org.baeldung.session.exception; + +import org.baeldung.boot.model.Foo; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Bean; +import org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean; + +@EntityScan(basePackageClasses = Foo.class) +@SpringBootApplication +public class Application { + public static void main(String[] args) { + System.setProperty("spring.config.name", "exception"); + System.setProperty("spring.profiles.active", "exception"); + SpringApplication.run(Application.class, args); + } + + @Bean + public HibernateJpaSessionFactoryBean sessionFactory() { + return new HibernateJpaSessionFactoryBean(); + } +} diff --git a/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepository.java b/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepository.java new file mode 100644 index 0000000000..679d691b26 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepository.java @@ -0,0 +1,10 @@ +package org.baeldung.session.exception.repository; + +import org.baeldung.boot.model.Foo; + +public interface FooRepository { + + void save(Foo foo); + + Foo get(Integer id); +} diff --git a/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java b/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java new file mode 100644 index 0000000000..83de888e5e --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java @@ -0,0 +1,25 @@ +package org.baeldung.session.exception.repository; + +import org.baeldung.boot.model.Foo; +import org.hibernate.SessionFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Repository; + +@Profile("exception") +@Repository +public class FooRepositoryImpl implements FooRepository { + @Autowired + private SessionFactory sessionFactory; + + @Override + public void save(Foo foo) { + sessionFactory.getCurrentSession().saveOrUpdate(foo); + } + + @Override + public Foo get(Integer id) { + return sessionFactory.getCurrentSession().get(Foo.class, id); + } + +} \ No newline at end of file diff --git a/spring-boot/src/main/resources/application.properties b/spring-boot/src/main/resources/application.properties index 78bcf4cc05..d30045d1dc 100644 --- a/spring-boot/src/main/resources/application.properties +++ b/spring-boot/src/main/resources/application.properties @@ -26,4 +26,6 @@ info.app.version=1.0.0 ## Spring Security Configurations security.user.name=admin1 security.user.password=secret1 -management.security.role=SUPERUSER \ No newline at end of file +management.security.role=SUPERUSER + +logging.level.org.springframework=INFO \ No newline at end of file diff --git a/spring-boot/src/main/resources/logback.xml b/spring-boot/src/main/resources/logback.xml new file mode 100644 index 0000000000..78913ee76f --- /dev/null +++ b/spring-boot/src/main/resources/logback.xml @@ -0,0 +1,14 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + \ No newline at end of file diff --git a/spring-boot/src/main/resources/templates/index.html b/spring-boot/src/main/resources/templates/index.html new file mode 100644 index 0000000000..2c4387ed10 --- /dev/null +++ b/spring-boot/src/main/resources/templates/index.html @@ -0,0 +1,19 @@ + + + WebJars Demo + + + + +


+
+ × + Success! It is working as we expected. +
+
+ + + + + + diff --git a/webjars/src/test/java/com/baeldung/WebjarsdemoApplicationTests.java b/spring-boot/src/test/java/com/baeldung/WebjarsdemoApplicationIntegrationTest.java similarity index 80% rename from webjars/src/test/java/com/baeldung/WebjarsdemoApplicationTests.java rename to spring-boot/src/test/java/com/baeldung/WebjarsdemoApplicationIntegrationTest.java index 284cda5d31..3558682b97 100644 --- a/webjars/src/test/java/com/baeldung/WebjarsdemoApplicationTests.java +++ b/spring-boot/src/test/java/com/baeldung/WebjarsdemoApplicationIntegrationTest.java @@ -9,10 +9,10 @@ import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = WebjarsdemoApplication.class) @WebAppConfiguration -public class WebjarsdemoApplicationTests { +public class WebjarsdemoApplicationIntegrationTest { - @Test - public void contextLoads() { - } + @Test + public void contextLoads() { + } } diff --git a/spring-boot/src/test/java/com/baeldung/git/CommitIdIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/git/CommitIdIntegrationTest.java new file mode 100644 index 0000000000..348d594c05 --- /dev/null +++ b/spring-boot/src/test/java/com/baeldung/git/CommitIdIntegrationTest.java @@ -0,0 +1,41 @@ +package com.baeldung.git; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = CommitIdApplication.class) +public class CommitIdIntegrationTest { + + private static final Logger LOG = LoggerFactory.getLogger(CommitIdIntegrationTest.class); + + @Value("${git.commit.message.short:UNKNOWN}") + private String commitMessage; + + @Value("${git.branch:UNKNOWN}") + private String branch; + + @Value("${git.commit.id:UNKNOWN}") + private String commitId; + + @Test + public void whenInjecting_shouldDisplay() throws Exception { + + LOG.info(commitId); + LOG.info(commitMessage); + LOG.info(branch); + + assertThat(commitMessage).isNotEqualTo("UNKNOWN"); + + assertThat(branch).isNotEqualTo("UNKNOWN"); + + assertThat(commitId).isNotEqualTo("UNKNOWN"); + } +} \ No newline at end of file diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootApplicationTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java similarity index 80% rename from spring-boot/src/test/java/org/baeldung/SpringBootApplicationTest.java rename to spring-boot/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java index ac7bcd62a9..3c5444942c 100644 --- a/spring-boot/src/test/java/org/baeldung/SpringBootApplicationTest.java +++ b/spring-boot/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java @@ -26,27 +26,20 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -public class SpringBootApplicationTest { +public class SpringBootApplicationIntegrationTest { @Autowired private WebApplicationContext webApplicationContext; private MockMvc mockMvc; - @Before public void setupMockMvc() { - mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) - .build(); + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); } @Test public void givenRequestHasBeenMade_whenMeetsAllOfGivenConditions_thenCorrect() throws Exception { - MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), - MediaType.APPLICATION_JSON.getSubtype(), - Charset.forName("utf8")); + MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8")); - mockMvc.perform(MockMvcRequestBuilders.get("/entity/all")). - andExpect(MockMvcResultMatchers.status().isOk()). - andExpect(MockMvcResultMatchers.content().contentType(contentType)). - andExpect(jsonPath("$", hasSize(4))); + mockMvc.perform(MockMvcRequestBuilders.get("/entity/all")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().contentType(contentType)).andExpect(jsonPath("$", hasSize(4))); } } diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootJPATest.java b/spring-boot/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java similarity index 95% rename from spring-boot/src/test/java/org/baeldung/SpringBootJPATest.java rename to spring-boot/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java index 8a6b5139fe..233684bc24 100644 --- a/spring-boot/src/test/java/org/baeldung/SpringBootJPATest.java +++ b/spring-boot/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java @@ -13,7 +13,7 @@ import static org.junit.Assert.assertNotNull; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) -public class SpringBootJPATest { +public class SpringBootJPAIntegrationTest { @Autowired private GenericEntityRepository genericEntityRepository; diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootMailTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java similarity index 98% rename from spring-boot/src/test/java/org/baeldung/SpringBootMailTest.java rename to spring-boot/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java index d36a7906a3..cec25f20f9 100644 --- a/spring-boot/src/test/java/org/baeldung/SpringBootMailTest.java +++ b/spring-boot/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java @@ -24,7 +24,7 @@ import static org.junit.Assert.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) -public class SpringBootMailTest { +public class SpringBootMailIntegrationTest { @Autowired private JavaMailSender javaMailSender; @@ -69,7 +69,6 @@ public class SpringBootMailTest { return wiserMessage.getMimeMessage().getSubject(); } - private SimpleMailMessage composeEmailMessage() { SimpleMailMessage mailMessage = new SimpleMailMessage(); mailMessage.setTo(userTo); diff --git a/spring-boot/src/test/java/org/baeldung/boot/ApplicationIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/boot/ApplicationIntegrationTest.java new file mode 100644 index 0000000000..57a8abc1ee --- /dev/null +++ b/spring-boot/src/test/java/org/baeldung/boot/ApplicationIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung.boot; + +import org.baeldung.session.exception.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = Application.class) +@TestPropertySource("classpath:exception.properties") +public class ApplicationIntegrationTest { + @Test + public void contextLoads() { + } +} diff --git a/spring-boot/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java new file mode 100644 index 0000000000..4fcea35b4a --- /dev/null +++ b/spring-boot/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung.boot; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = DemoApplication.class) +@WebAppConfiguration +public class DemoApplicationIntegrationTest { + + @Test + public void contextLoads() { + } +} diff --git a/spring-boot/src/test/java/org/baeldung/boot/repository/FooRepositoryTest.java b/spring-boot/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java similarity index 84% rename from spring-boot/src/test/java/org/baeldung/boot/repository/FooRepositoryTest.java rename to spring-boot/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java index 9de7790a75..a844b26b2d 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/repository/FooRepositoryTest.java +++ b/spring-boot/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java @@ -2,7 +2,7 @@ package org.baeldung.boot.repository; import static org.junit.Assert.assertThat; -import org.baeldung.boot.DemoApplicationTests; +import org.baeldung.boot.DemoApplicationIntegrationTest; import org.baeldung.boot.model.Foo; import static org.hamcrest.Matchers.notNullValue; @@ -14,7 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; @Transactional -public class FooRepositoryTest extends DemoApplicationTests { +public class FooRepositoryIntegrationTest extends DemoApplicationIntegrationTest { @Autowired private FooRepository fooRepository; diff --git a/spring-boot/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java new file mode 100644 index 0000000000..be992bcc36 --- /dev/null +++ b/spring-boot/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java @@ -0,0 +1,32 @@ +package org.baeldung.boot.repository; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; + +import org.baeldung.boot.ApplicationIntegrationTest; +import org.baeldung.boot.model.Foo; +import org.baeldung.session.exception.repository.FooRepository; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.TestPropertySource; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@TestPropertySource("classpath:exception-hibernate.properties") +public class HibernateSessionIntegrationTest extends ApplicationIntegrationTest { + @Autowired + private FooRepository fooRepository; + + @Test + public void whenSavingWithCurrentSession_thenThrowNoException() { + Foo foo = new Foo("Exception Solved"); + fooRepository.save(foo); + foo = null; + foo = fooRepository.get(1); + + assertThat(foo, notNullValue()); + assertThat(foo.getId(), is(1)); + assertThat(foo.getName(), is("Exception Solved")); + } +} diff --git a/spring-boot/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java new file mode 100644 index 0000000000..55b7fa7216 --- /dev/null +++ b/spring-boot/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java @@ -0,0 +1,21 @@ +package org.baeldung.boot.repository; + +import org.baeldung.boot.ApplicationIntegrationTest; +import org.baeldung.boot.model.Foo; +import org.baeldung.session.exception.repository.FooRepository; +import org.hibernate.HibernateException; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +public class NoHibernateSessionIntegrationTest extends ApplicationIntegrationTest { + @Autowired + private FooRepository fooRepository; + + @Test(expected = HibernateException.class) + public void whenSavingWithoutCurrentSession_thenThrowException() { + Foo foo = new Foo("Exception Thrown"); + fooRepository.save(foo); + } +} diff --git a/spring-boot/src/test/java/org/baeldung/client/DetailsServiceClientTest.java b/spring-boot/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java similarity index 88% rename from spring-boot/src/test/java/org/baeldung/client/DetailsServiceClientTest.java rename to spring-boot/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java index c594610be2..5627855aa3 100644 --- a/spring-boot/src/test/java/org/baeldung/client/DetailsServiceClientTest.java +++ b/spring-boot/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java @@ -16,7 +16,7 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat @RunWith(SpringRunner.class) @RestClientTest(DetailsServiceClient.class) -public class DetailsServiceClientTest { +public class DetailsServiceClientIntegrationTest { @Autowired private DetailsServiceClient client; @@ -30,8 +30,7 @@ public class DetailsServiceClientTest { @Before public void setUp() throws Exception { String detailsString = objectMapper.writeValueAsString(new Details("John Smith", "john")); - this.server.expect(requestTo("/john/details")) - .andRespond(withSuccess(detailsString, MediaType.APPLICATION_JSON)); + this.server.expect(requestTo("/john/details")).andRespond(withSuccess(detailsString, MediaType.APPLICATION_JSON)); } @Test diff --git a/spring-boot/src/test/resources/exception-hibernate.properties b/spring-boot/src/test/resources/exception-hibernate.properties new file mode 100644 index 0000000000..cde746acb9 --- /dev/null +++ b/spring-boot/src/test/resources/exception-hibernate.properties @@ -0,0 +1,2 @@ +spring.profiles.active=exception +spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext diff --git a/spring-boot/src/test/resources/exception.properties b/spring-boot/src/test/resources/exception.properties new file mode 100644 index 0000000000..c55e415a3a --- /dev/null +++ b/spring-boot/src/test/resources/exception.properties @@ -0,0 +1,6 @@ +# Security +security.user.name=admin +security.user.password=password + +spring.dao.exceptiontranslation.enabled=false +spring.profiles.active=exception \ No newline at end of file diff --git a/spring-cloud-data-flow/README.MD b/spring-cloud-data-flow/README.MD new file mode 100644 index 0000000000..17d0ec6286 --- /dev/null +++ b/spring-cloud-data-flow/README.MD @@ -0,0 +1,3 @@ +### Relevant Articles: +- [Batch Processing with Spring Cloud Data Flow](http://www.baeldung.com/spring-cloud-data-flow-batch-processing) +- [Getting Started with Stream Processing with Spring Cloud Data Flow](http://www.baeldung.com/spring-cloud-data-flow-stream-processing) diff --git a/spring-cloud-data-flow/batch-job/pom.xml b/spring-cloud-data-flow/batch-job/pom.xml new file mode 100644 index 0000000000..99e57d4c20 --- /dev/null +++ b/spring-cloud-data-flow/batch-job/pom.xml @@ -0,0 +1,83 @@ + + + 4.0.0 + + org.baeldung.spring.cloud + batch-job + 0.0.1-SNAPSHOT + jar + + batch-job + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.cloud + spring-cloud-task-starter + 1.0.1.RELEASE + + + + org.springframework.boot + spring-boot-starter-batch + + + + com.h2database + h2 + runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + Brixton.SR5 + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + diff --git a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java new file mode 100644 index 0000000000..f717f0f644 --- /dev/null +++ b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java @@ -0,0 +1,16 @@ +package org.baeldung.spring.cloud; + +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.task.configuration.EnableTask; + +@EnableTask +@EnableBatchProcessing +@SpringBootApplication +public class BatchJobApplication { + + public static void main(String[] args) { + SpringApplication.run(BatchJobApplication.class, args); + } +} diff --git a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java new file mode 100644 index 0000000000..dc6a5e2827 --- /dev/null +++ b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java @@ -0,0 +1,38 @@ +package org.baeldung.spring.cloud; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.batch.core.Job; +import org.springframework.batch.core.StepContribution; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.scope.context.ChunkContext; +import org.springframework.batch.core.step.tasklet.Tasklet; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class JobConfiguration { + + private static final Log logger = LogFactory.getLog(JobConfiguration.class); + + @Autowired + public JobBuilderFactory jobBuilderFactory; + + @Autowired + public StepBuilderFactory stepBuilderFactory; + + @Bean + public Job job() { + return jobBuilderFactory.get("job").start(stepBuilderFactory.get("jobStep1").tasklet(new Tasklet() { + @Override + public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { + logger.info("Job was run"); + return RepeatStatus.FINISHED; + } + }).build()).build(); + } +} diff --git a/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java b/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java new file mode 100644 index 0000000000..f8dfdec197 --- /dev/null +++ b/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung.spring.cloud; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class BatchJobApplicationIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud-data-flow/data-flow-server/pom.xml b/spring-cloud-data-flow/data-flow-server/pom.xml new file mode 100644 index 0000000000..451a58e12a --- /dev/null +++ b/spring-cloud-data-flow/data-flow-server/pom.xml @@ -0,0 +1,132 @@ + + + 4.0.0 + + org.baeldung.spring.cloud + data-flow-server + 0.0.1-SNAPSHOT + jar + + data-flow-server + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.cloud + spring-cloud-starter-dataflow-server-local + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.cloud + spring-cloud-dataflow-dependencies + 1.0.0.BUILD-SNAPSHOT + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + Brixton.SR5 + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + diff --git a/spring-cloud-data-flow/data-flow-server/src/main/java/org/baeldung/spring/cloud/DataFlowServerApplication.java b/spring-cloud-data-flow/data-flow-server/src/main/java/org/baeldung/spring/cloud/DataFlowServerApplication.java new file mode 100644 index 0000000000..227c10b620 --- /dev/null +++ b/spring-cloud-data-flow/data-flow-server/src/main/java/org/baeldung/spring/cloud/DataFlowServerApplication.java @@ -0,0 +1,14 @@ +package org.baeldung.spring.cloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.dataflow.server.EnableDataFlowServer; + +@EnableDataFlowServer +@SpringBootApplication +public class DataFlowServerApplication { + + public static void main(String[] args) { + SpringApplication.run(DataFlowServerApplication.class, args); + } +} diff --git a/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java b/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java new file mode 100644 index 0000000000..bb8660b816 --- /dev/null +++ b/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung.spring.cloud; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class DataFlowServerApplicationIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud-data-flow/data-flow-shell/pom.xml b/spring-cloud-data-flow/data-flow-shell/pom.xml new file mode 100644 index 0000000000..31d3dce507 --- /dev/null +++ b/spring-cloud-data-flow/data-flow-shell/pom.xml @@ -0,0 +1,97 @@ + + + 4.0.0 + + org.baeldung.spring.cloud + data-flow-shell + 0.0.1-SNAPSHOT + jar + + data-flow-shell + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.cloud + spring-cloud-dataflow-shell + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.cloud + spring-cloud-dataflow-dependencies + 1.0.0.BUILD-SNAPSHOT + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + Brixton.SR5 + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + diff --git a/spring-cloud-data-flow/data-flow-shell/spring-shell.log b/spring-cloud-data-flow/data-flow-shell/spring-shell.log new file mode 100644 index 0000000000..92a8488c7d --- /dev/null +++ b/spring-cloud-data-flow/data-flow-shell/spring-shell.log @@ -0,0 +1,2 @@ +// dataflow 1.2.0.RELEASE log opened at 2016-10-20 13:13:20 +// dataflow 1.2.0.RELEASE log opened at 2016-10-24 16:51:17 diff --git a/spring-cloud-data-flow/data-flow-shell/src/main/java/org/baeldung/spring/cloud/DataFlowShellApplication.java b/spring-cloud-data-flow/data-flow-shell/src/main/java/org/baeldung/spring/cloud/DataFlowShellApplication.java new file mode 100644 index 0000000000..36c421f5bf --- /dev/null +++ b/spring-cloud-data-flow/data-flow-shell/src/main/java/org/baeldung/spring/cloud/DataFlowShellApplication.java @@ -0,0 +1,14 @@ +package org.baeldung.spring.cloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.dataflow.shell.EnableDataFlowShell; + +@EnableDataFlowShell +@SpringBootApplication +public class DataFlowShellApplication { + + public static void main(String[] args) { + SpringApplication.run(DataFlowShellApplication.class, args); + } +} diff --git a/spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/spring/cloud/DataFlowShellApplicationIntegrationTest.java b/spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/spring/cloud/DataFlowShellApplicationIntegrationTest.java new file mode 100644 index 0000000000..5ab3292388 --- /dev/null +++ b/spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/spring/cloud/DataFlowShellApplicationIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung.spring.cloud; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class DataFlowShellApplicationIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud-data-flow/log-sink/pom.xml b/spring-cloud-data-flow/log-sink/pom.xml new file mode 100644 index 0000000000..db488c05ef --- /dev/null +++ b/spring-cloud-data-flow/log-sink/pom.xml @@ -0,0 +1,105 @@ + + + 4.0.0 + + org.baeldung.spring.cloud + log-sink + 0.0.1-SNAPSHOT + jar + + log-sink + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + Brixton.SR5 + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + diff --git a/spring-cloud-data-flow/log-sink/src/main/java/org/baeldung/spring/cloud/LogSinkApplication.java b/spring-cloud-data-flow/log-sink/src/main/java/org/baeldung/spring/cloud/LogSinkApplication.java new file mode 100644 index 0000000000..a2b9968539 --- /dev/null +++ b/spring-cloud-data-flow/log-sink/src/main/java/org/baeldung/spring/cloud/LogSinkApplication.java @@ -0,0 +1,26 @@ +package org.baeldung.spring.cloud; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.cloud.stream.messaging.Sink; + +@EnableBinding(Sink.class) +@SpringBootApplication +public class LogSinkApplication { + + private static Logger logger = LoggerFactory.getLogger(LogSinkApplication.class); + + @StreamListener(Sink.INPUT) + public void loggerSink(String date) { + + logger.info("Received: " + date); + } + + public static void main(String[] args) { + SpringApplication.run(LogSinkApplication.class, args); + } +} diff --git a/spring-cloud-data-flow/log-sink/src/test/java/org/baeldung/spring/cloud/LogSinkApplicationIntegrationTest.java b/spring-cloud-data-flow/log-sink/src/test/java/org/baeldung/spring/cloud/LogSinkApplicationIntegrationTest.java new file mode 100644 index 0000000000..b362d72705 --- /dev/null +++ b/spring-cloud-data-flow/log-sink/src/test/java/org/baeldung/spring/cloud/LogSinkApplicationIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung.spring.cloud; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class LogSinkApplicationIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud-data-flow/pom.xml b/spring-cloud-data-flow/pom.xml new file mode 100644 index 0000000000..509c185d61 --- /dev/null +++ b/spring-cloud-data-flow/pom.xml @@ -0,0 +1,15 @@ + + 4.0.0 + org.baeldung.spring.cloud + spring-cloud-data-flow + 0.0.1-SNAPSHOT + pom + + data-flow-server + data-flow-shell + time-source + time-processor + log-sink + batch-job + + diff --git a/spring-cloud-data-flow/time-processor/pom.xml b/spring-cloud-data-flow/time-processor/pom.xml new file mode 100644 index 0000000000..8277c9c836 --- /dev/null +++ b/spring-cloud-data-flow/time-processor/pom.xml @@ -0,0 +1,105 @@ + + + 4.0.0 + + org.baeldung.spring.cloud + time-processor + 0.0.1-SNAPSHOT + jar + + time-processor + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + Brixton.SR5 + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + diff --git a/spring-cloud-data-flow/time-processor/src/main/java/org/baeldung/spring/cloud/TimeProcessorApplication.java b/spring-cloud-data-flow/time-processor/src/main/java/org/baeldung/spring/cloud/TimeProcessorApplication.java new file mode 100644 index 0000000000..7a2763d436 --- /dev/null +++ b/spring-cloud-data-flow/time-processor/src/main/java/org/baeldung/spring/cloud/TimeProcessorApplication.java @@ -0,0 +1,27 @@ +package org.baeldung.spring.cloud; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.messaging.Processor; +import org.springframework.integration.annotation.Transformer; + +@EnableBinding(Processor.class) +@SpringBootApplication +public class TimeProcessorApplication { + + @Transformer(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT) + public Object transform(Long timestamp) { + + DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss"); + String date = dateFormat.format(timestamp); + return date; + } + + public static void main(String[] args) { + SpringApplication.run(TimeProcessorApplication.class, args); + } +} diff --git a/spring-cloud-data-flow/time-processor/src/test/java/org/baeldung/spring/cloud/TimeProcessorApplicationIntegrationTest.java b/spring-cloud-data-flow/time-processor/src/test/java/org/baeldung/spring/cloud/TimeProcessorApplicationIntegrationTest.java new file mode 100644 index 0000000000..9bd0fd8c24 --- /dev/null +++ b/spring-cloud-data-flow/time-processor/src/test/java/org/baeldung/spring/cloud/TimeProcessorApplicationIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung.spring.cloud; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class TimeProcessorApplicationIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud-data-flow/time-source/pom.xml b/spring-cloud-data-flow/time-source/pom.xml new file mode 100644 index 0000000000..086d761f78 --- /dev/null +++ b/spring-cloud-data-flow/time-source/pom.xml @@ -0,0 +1,105 @@ + + + 4.0.0 + + org.baeldung.spring.cloud + time-source + 0.0.1-SNAPSHOT + jar + + time-source + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + Brixton.SR5 + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + diff --git a/spring-cloud-data-flow/time-source/src/main/java/org/baeldung/spring/cloud/TimeSourceApplication.java b/spring-cloud-data-flow/time-source/src/main/java/org/baeldung/spring/cloud/TimeSourceApplication.java new file mode 100644 index 0000000000..5bce39ebe0 --- /dev/null +++ b/spring-cloud-data-flow/time-source/src/main/java/org/baeldung/spring/cloud/TimeSourceApplication.java @@ -0,0 +1,29 @@ +package org.baeldung.spring.cloud; + +import java.util.Date; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.messaging.Source; +import org.springframework.context.annotation.Bean; +import org.springframework.integration.annotation.InboundChannelAdapter; +import org.springframework.integration.annotation.Poller; +import org.springframework.integration.core.MessageSource; +import org.springframework.integration.support.MessageBuilder; + +@EnableBinding(Source.class) +@SpringBootApplication +public class TimeSourceApplication { + + @Bean + @InboundChannelAdapter(value = Source.OUTPUT, poller = @Poller(fixedDelay = "10000", maxMessagesPerPoll = "1")) + public MessageSource timeMessageSource() { + + return () -> MessageBuilder.withPayload(new Date().getTime()).build(); + } + + public static void main(String[] args) { + SpringApplication.run(TimeSourceApplication.class, args); + } +} diff --git a/spring-cloud-data-flow/time-source/src/test/java/org/baeldung/spring/cloud/TimeSourceApplicationIntegrationTest.java b/spring-cloud-data-flow/time-source/src/test/java/org/baeldung/spring/cloud/TimeSourceApplicationIntegrationTest.java new file mode 100644 index 0000000000..6d71a785a3 --- /dev/null +++ b/spring-cloud-data-flow/time-source/src/test/java/org/baeldung/spring/cloud/TimeSourceApplicationIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung.spring.cloud; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class TimeSourceApplicationIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud/README.md b/spring-cloud/README.md new file mode 100644 index 0000000000..60acdaeed5 --- /dev/null +++ b/spring-cloud/README.md @@ -0,0 +1,19 @@ +## The Module Holds Sources for the Following Articles + +- [Quick Intro to Spring Cloud Configuration](http://www.baeldung.com/spring-cloud-configuration) + + Spring Cloud Config is Spring’s client/server approach for storing and serving distributed configurations across multiple applications and environments. + + In this write-up, we’ll focus on an example of how to setup a Git-backed config server, use it in a simple REST application server and setup a secure environment including encrypted property values. + +- [Introduction to Spring Cloud Netflix – Eureka](http://www.baeldung.com/spring-cloud-netflix-eureka) + + In this article, we’ll introduce client-side service discovery via “Spring Cloud Netflix Eureka“. + + Client-side service discovery allows services to find and communicate with each other without hardcoding hostname and port. The only ‘fixed point’ in such an architecture consists of a service registry with which each service has to register. + +- [Intro to Spring Cloud Netflix - Hystrix](http://www.baeldung.com/spring-cloud-netflix-hystrix) +- [Dockerizing a Spring Boot Application](http://www.baeldung.com/dockerizing-spring-boot-application) +- [Introduction to Spring Cloud Rest Client with Netflix Ribbon](http://www.baeldung.com/spring-cloud-rest-client-with-netflix-ribbon) + + diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml new file mode 100644 index 0000000000..455a5b876b --- /dev/null +++ b/spring-cloud/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + com.baeldung.spring.cloud + spring-cloud + 1.0.0-SNAPSHOT + + spring-cloud-config + spring-cloud-eureka + spring-cloud-hystrix + spring-cloud-bootstrap + spring-cloud-ribbon-client + + pom + + spring-cloud + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + .. + + + + UTF-8 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-maven-plugin + 1.4.0.RELEASE + + + + + diff --git a/spring-cloud/spring-cloud-bootstrap/README.MD b/spring-cloud/spring-cloud-bootstrap/README.MD new file mode 100644 index 0000000000..c16ba3e247 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/README.MD @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Spring Cloud – Bootstrapping](http://www.baeldung.com/spring-cloud-bootstrapping) diff --git a/spring-cloud/spring-cloud-bootstrap/application-config/discovery.properties b/spring-cloud/spring-cloud-bootstrap/application-config/discovery.properties new file mode 100644 index 0000000000..e6ca72cf69 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/application-config/discovery.properties @@ -0,0 +1,11 @@ +spring.application.name=discovery +server.port=8082 + +eureka.instance.hostname=localhost + +eureka.client.serviceUrl.defaultZone=http://discUser:discPassword@localhost:8082/eureka/ +eureka.client.register-with-eureka=false +eureka.client.fetch-registry=false + +spring.redis.host=localhost +spring.redis.port=6379 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/application-config/gateway.properties b/spring-cloud/spring-cloud-bootstrap/application-config/gateway.properties new file mode 100644 index 0000000000..6f52a59db9 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/application-config/gateway.properties @@ -0,0 +1,23 @@ +spring.application.name=gateway +server.port=8080 + +eureka.client.region = default +eureka.client.registryFetchIntervalSeconds = 5 + +management.security.sessions=always + +zuul.routes.resource.path=/resource/** +zuul.routes.resource.sensitive-headers=Set-Cookie,Authorization +hystrix.command.resource.execution.isolation.thread.timeoutInMilliseconds=600000 + +zuul.routes.discovery.path=/discovery/** +zuul.routes.discovery.sensitive-headers=Set-Cookie,Authorization +zuul.routes.discovery.url=http://localhost:8082 +hystrix.command.discovery.execution.isolation.thread.timeoutInMilliseconds=600000 + +logging.level.org.springframework.web.=debug +logging.level.org.springframework.security=debug +logging.level.org.springframework.cloud.netflix.zuul=debug + +spring.redis.host=localhost +spring.redis.port=6379 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/application-config/resource.properties b/spring-cloud/spring-cloud-bootstrap/application-config/resource.properties new file mode 100644 index 0000000000..9fb610d655 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/application-config/resource.properties @@ -0,0 +1,17 @@ +spring.application.name=resource +server.port=8083 + +resource.returnString=hello cloud +resource.user.returnString=hello cloud user +resource.admin.returnString=hello cloud admin + +eureka.client.region = default +eureka.client.registryFetchIntervalSeconds = 5 + +management.security.sessions=never + +logging.level.org.springframework.web.=debug +logging.level.org.springframework.security=debug + +spring.redis.host=localhost +spring.redis.port=6379 diff --git a/spring-cloud/spring-cloud-bootstrap/config/pom.xml b/spring-cloud/spring-cloud-bootstrap/config/pom.xml new file mode 100644 index 0000000000..bcb40ac062 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/config/pom.xml @@ -0,0 +1,67 @@ + + + 4.0.0 + + config + 1.0.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + + + + org.springframework.cloud + spring-cloud-config-server + + + org.springframework.cloud + spring-cloud-starter-eureka + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-security + + + + + + + org.springframework.cloud + spring-cloud-dependencies + Brixton.RELEASE + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 1.8 + 1.8 + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/config/src/main/java/com/baeldung/spring/cloud/bootstrap/config/ConfigApplication.java b/spring-cloud/spring-cloud-bootstrap/config/src/main/java/com/baeldung/spring/cloud/bootstrap/config/ConfigApplication.java new file mode 100644 index 0000000000..847c86f881 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/config/src/main/java/com/baeldung/spring/cloud/bootstrap/config/ConfigApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.spring.cloud.bootstrap.config; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; + +@SpringBootApplication +@EnableConfigServer +@EnableEurekaClient +public class ConfigApplication { + public static void main(String[] args) { + SpringApplication.run(ConfigApplication.class, args); + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/config/src/main/java/com/baeldung/spring/cloud/bootstrap/config/SecurityConfig.java b/spring-cloud/spring-cloud-bootstrap/config/src/main/java/com/baeldung/spring/cloud/bootstrap/config/SecurityConfig.java new file mode 100644 index 0000000000..e607144f11 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/config/src/main/java/com/baeldung/spring/cloud/bootstrap/config/SecurityConfig.java @@ -0,0 +1,29 @@ +package com.baeldung.spring.cloud.bootstrap.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{ + auth.inMemoryAuthentication().withUser("configUser").password("configPassword").roles("SYSTEM"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .anyRequest().hasRole("SYSTEM") + .and() + .httpBasic() + .and() + .csrf() + .disable(); + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/config/src/main/resources/application.properties b/spring-cloud/spring-cloud-bootstrap/config/src/main/resources/application.properties new file mode 100644 index 0000000000..6c47d001f4 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/config/src/main/resources/application.properties @@ -0,0 +1,8 @@ +server.port=8081 +spring.application.name=config + +spring.cloud.config.server.git.uri=file:///${user.home}/application-config + +eureka.client.region = default +eureka.client.registryFetchIntervalSeconds = 5 +eureka.client.serviceUrl.defaultZone=http://discUser:discPassword@localhost:8082/eureka/ \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml b/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml new file mode 100644 index 0000000000..f3cb3be2af --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + discovery + 1.0.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.cloud + spring-cloud-starter-eureka-server + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.session + spring-session + 1.2.1.RELEASE + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + + + org.springframework.cloud + spring-cloud-dependencies + Brixton.RELEASE + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/DiscoveryApplication.java b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/DiscoveryApplication.java new file mode 100644 index 0000000000..32bcdc90b6 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/DiscoveryApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.cloud.bootstrap.discovery; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; + +@SpringBootApplication +@EnableEurekaServer +public class DiscoveryApplication { + public static void main(String[] args) { + SpringApplication.run(DiscoveryApplication.class, args); + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/SecurityConfig.java b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/SecurityConfig.java new file mode 100644 index 0000000000..b559da6394 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/SecurityConfig.java @@ -0,0 +1,65 @@ +package com.baeldung.spring.cloud.bootstrap.discovery; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpMethod; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; + +@Configuration +@EnableWebSecurity +@Order(1) +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{ + auth.inMemoryAuthentication().withUser("discUser").password("discPassword").roles("SYSTEM"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.ALWAYS) + .and() + .requestMatchers() + .antMatchers("/eureka/**") + .and() + .authorizeRequests() + .antMatchers("/eureka/**").hasRole("SYSTEM") + .anyRequest().denyAll() + .and() + .httpBasic() + .and() + .csrf() + .disable(); + } + + @Configuration + //no order tag means this is the last security filter to be evaluated + public static class AdminSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication(); + } + + @Override protected void configure(HttpSecurity http) throws Exception { + http + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.NEVER) + .and() + .httpBasic() + .disable() + .authorizeRequests() + .antMatchers(HttpMethod.GET, "/").hasRole("ADMIN") + .antMatchers("/info","/health").authenticated() + .anyRequest().denyAll() + .and() + .csrf() + .disable(); + } + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/SessionConfig.java b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/SessionConfig.java new file mode 100644 index 0000000000..83e5f51c97 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/SessionConfig.java @@ -0,0 +1,8 @@ +package com.baeldung.spring.cloud.bootstrap.discovery; + +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; +import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; + +@EnableRedisHttpSession +public class SessionConfig extends AbstractHttpSessionApplicationInitializer { +} diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/resources/bootstrap.properties new file mode 100644 index 0000000000..d31caf55b5 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/resources/bootstrap.properties @@ -0,0 +1,4 @@ +spring.cloud.config.name=discovery +spring.cloud.config.uri=http://localhost:8081 +spring.cloud.config.username=configUser +spring.cloud.config.password=configPassword \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml b/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml new file mode 100644 index 0000000000..add551ff95 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml @@ -0,0 +1,81 @@ + + + 4.0.0 + + gateway + 1.0.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.cloud + spring-cloud-starter-eureka + + + org.springframework.cloud + spring-cloud-starter-zuul + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.session + spring-session + 1.2.1.RELEASE + + + org.springframework.boot + spring-boot-starter-data-redis + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + Brixton.RELEASE + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java new file mode 100644 index 0000000000..a3d2df5357 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java @@ -0,0 +1,40 @@ +package com.baeldung.spring.cloud.bootstrap.gateway; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; +import org.springframework.cloud.netflix.ribbon.RibbonClientSpecification; +import org.springframework.cloud.netflix.ribbon.SpringClientFactory; +import org.springframework.cloud.netflix.zuul.EnableZuulProxy; +import org.springframework.context.annotation.Bean; +import org.springframework.web.client.RestTemplate; + +import java.util.ArrayList; +import java.util.List; + +@SpringBootApplication +@EnableZuulProxy +@EnableEurekaClient +public class GatewayApplication { + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + + @Autowired(required = false) + private List configurations = new ArrayList<>(); + + @Bean + @LoadBalanced RestTemplate restTemplate(){ + return new RestTemplate(); + } + + + @Bean + public SpringClientFactory springClientFactory() { + SpringClientFactory factory = new SpringClientFactory(); + factory.setConfigurations(this.configurations); + return factory; + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java new file mode 100644 index 0000000000..60dccf9042 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java @@ -0,0 +1,37 @@ +package com.baeldung.spring.cloud.bootstrap.gateway; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@EnableWebSecurity +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .withUser("user").password("password").roles("USER") + .and() + .withUser("admin").password("admin").roles("ADMIN"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/resource/hello/cloud").permitAll() + .antMatchers("/eureka/**").hasRole("ADMIN") + .anyRequest().authenticated() + .and() + .formLogin() + .and() + .logout().permitAll() + .logoutSuccessUrl("/resource/hello/cloud").permitAll() + .and() + .csrf() + .disable(); + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SessionConfig.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SessionConfig.java new file mode 100644 index 0000000000..14f7deb770 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SessionConfig.java @@ -0,0 +1,11 @@ +package com.baeldung.spring.cloud.bootstrap.gateway; + +import org.springframework.context.annotation.Configuration; +import org.springframework.session.data.redis.RedisFlushMode; +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; +import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; + +@Configuration +@EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE) +public class SessionConfig extends AbstractHttpSessionApplicationInitializer { +} diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/filter/SessionSavingZuulPreFilter.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/filter/SessionSavingZuulPreFilter.java new file mode 100644 index 0000000000..9a2b5bab74 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/filter/SessionSavingZuulPreFilter.java @@ -0,0 +1,47 @@ +package com.baeldung.spring.cloud.bootstrap.gateway.filter; + +import com.netflix.zuul.ZuulFilter; +import com.netflix.zuul.context.RequestContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.session.Session; +import org.springframework.session.SessionRepository; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpSession; + +@Component +public class SessionSavingZuulPreFilter extends ZuulFilter { + + private Logger log = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private SessionRepository repository; + + @Override public boolean shouldFilter() { + return true; + } + + @Override + public Object run() { + RequestContext context = RequestContext.getCurrentContext(); + + HttpSession httpSession = context.getRequest().getSession(); + Session session = repository.getSession(httpSession.getId()); + + context.addZuulRequestHeader("Cookie", "SESSION=" + httpSession.getId()); + + log.info("ZuulPreFilter session proxy: {}", session.getId()); + + return null; + } + + @Override public String filterType() { + return "pre"; + } + + @Override public int filterOrder() { + return 0; + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/bootstrap.properties new file mode 100644 index 0000000000..43491ff36b --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/bootstrap.properties @@ -0,0 +1,7 @@ +spring.cloud.config.name=gateway +spring.cloud.config.discovery.service-id=config +spring.cloud.config.discovery.enabled=true +spring.cloud.config.username=configUser +spring.cloud.config.password=configPassword + +eureka.client.serviceUrl.defaultZone=http://discUser:discPassword@localhost:8082/eureka/ \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/css/wro.css b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/css/wro.css new file mode 100644 index 0000000000..e023c0a145 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/css/wro.css @@ -0,0 +1,6393 @@ +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + font-size: 2em; + margin: 0.67em 0; +} +mark { + background: #ff0; + color: #000; +} +small { + font-size: 80%; +} +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + color: inherit; + font: inherit; + margin: 0; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-appearance: textfield; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} +legend { + border: 0; + padding: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +td, +th { + padding: 0; +} +@media print { + * { + text-shadow: none !important; + color: #000 !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + select { + background: #fff !important; + } + .navbar { + display: none; + } + .table td, + .table th { + background-color: #fff !important; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +@font-face { + font-family: 'Glyphicons Halflings'; + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\2a"; +} +.glyphicon-plus:before { + content: "\2b"; +} +.glyphicon-euro:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 10px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.428571429; + color: #f1f1f1; + background-color: #f1f1f1; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #5fa134; + text-decoration: none; +} +a:hover, +a:focus { + color: #5fa134; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + width: 100% \9; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 0; +} +.img-thumbnail { + padding: 4px; + line-height: 1.428571429; + background-color: #f1f1f1; + border: 1px solid #ddd; + border-radius: 0; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; + display: inline-block; + width: 100% \9; + max-width: 100%; + height: auto; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eeeeee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #777777; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 20px; + margin-bottom: 10px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 10px; + margin-bottom: 10px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 30px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 14px; +} +h6, +.h6 { + font-size: 12px; +} +p { + margin: 0 0 10px; +} +.lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 300; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} +small, +.small { + font-size: 85%; +} +cite { + font-style: normal; +} +mark, +.mark { + background-color: #fcf8e3; + padding: .2em; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-nowrap { + white-space: nowrap; +} +.text-lowercase { + text-transform: lowercase; +} +.text-uppercase { + text-transform: uppercase; +} +.text-capitalize { + text-transform: capitalize; +} +.text-muted { + color: #777777; +} +.text-primary { + color: #428bca; +} +a.text-primary:hover { + color: #3071a9; +} +.text-success { + color: #3c763d; +} +a.text-success:hover { + color: #2b542c; +} +.text-info { + color: #31708f; +} +a.text-info:hover { + color: #245269; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover { + color: #66512c; +} +.text-danger { + color: #a94442; +} +a.text-danger:hover { + color: #843534; +} +.bg-primary { + color: #fff; + background-color: #428bca; +} +a.bg-primary:hover { + background-color: #3071a9; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eeeeee; +} +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + list-style: none; + margin-left: -5px; +} +.list-inline > li { + display: inline-block; + padding-left: 5px; + padding-right: 5px; +} +dl { + margin-top: 0; + margin-bottom: 20px; +} +dt, +dd { + line-height: 1.428571429; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #777777; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eeeeee; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.428571429; + color: #777777; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; + text-align: right; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +blockquote:before, +blockquote:after { + content: ""; +} +address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.428571429; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 0; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 0; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); +} +kbd kbd { + padding: 0; + font-size: 100%; + box-shadow: none; +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.428571429; + word-break: break-all; + word-wrap: break-word; + color: #333333; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 0; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} +.row { + margin-left: -15px; + margin-right: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666666666666%; +} +.col-xs-10 { + width: 83.33333333333334%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666666666666%; +} +.col-xs-7 { + width: 58.333333333333336%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666666666667%; +} +.col-xs-4 { + width: 33.33333333333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.666666666666664%; +} +.col-xs-1 { + width: 8.333333333333332%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666666666666%; +} +.col-xs-pull-10 { + right: 83.33333333333334%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666666666666%; +} +.col-xs-pull-7 { + right: 58.333333333333336%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666666666667%; +} +.col-xs-pull-4 { + right: 33.33333333333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.666666666666664%; +} +.col-xs-pull-1 { + right: 8.333333333333332%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666666666666%; +} +.col-xs-push-10 { + left: 83.33333333333334%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666666666666%; +} +.col-xs-push-7 { + left: 58.333333333333336%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666666666667%; +} +.col-xs-push-4 { + left: 33.33333333333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.666666666666664%; +} +.col-xs-push-1 { + left: 8.333333333333332%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666666666666%; +} +.col-xs-offset-10 { + margin-left: 83.33333333333334%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666666666666%; +} +.col-xs-offset-7 { + margin-left: 58.333333333333336%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666666666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.666666666666664%; +} +.col-xs-offset-1 { + margin-left: 8.333333333333332%; +} +.col-xs-offset-0 { + margin-left: 0%; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666666666666%; + } + .col-sm-10 { + width: 83.33333333333334%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666666666666%; + } + .col-sm-7 { + width: 58.333333333333336%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666666666667%; + } + .col-sm-4 { + width: 33.33333333333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.666666666666664%; + } + .col-sm-1 { + width: 8.333333333333332%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666666666666%; + } + .col-sm-pull-10 { + right: 83.33333333333334%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666666666666%; + } + .col-sm-pull-7 { + right: 58.333333333333336%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666666666667%; + } + .col-sm-pull-4 { + right: 33.33333333333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.666666666666664%; + } + .col-sm-pull-1 { + right: 8.333333333333332%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666666666666%; + } + .col-sm-push-10 { + left: 83.33333333333334%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666666666666%; + } + .col-sm-push-7 { + left: 58.333333333333336%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666666666667%; + } + .col-sm-push-4 { + left: 33.33333333333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.666666666666664%; + } + .col-sm-push-1 { + left: 8.333333333333332%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666666666666%; + } + .col-sm-offset-10 { + margin-left: 83.33333333333334%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666666666666%; + } + .col-sm-offset-7 { + margin-left: 58.333333333333336%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666666666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.666666666666664%; + } + .col-sm-offset-1 { + margin-left: 8.333333333333332%; + } + .col-sm-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666666666666%; + } + .col-md-10 { + width: 83.33333333333334%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666666666666%; + } + .col-md-7 { + width: 58.333333333333336%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666666666667%; + } + .col-md-4 { + width: 33.33333333333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.666666666666664%; + } + .col-md-1 { + width: 8.333333333333332%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666666666666%; + } + .col-md-pull-10 { + right: 83.33333333333334%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666666666666%; + } + .col-md-pull-7 { + right: 58.333333333333336%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666666666667%; + } + .col-md-pull-4 { + right: 33.33333333333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.666666666666664%; + } + .col-md-pull-1 { + right: 8.333333333333332%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666666666666%; + } + .col-md-push-10 { + left: 83.33333333333334%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666666666666%; + } + .col-md-push-7 { + left: 58.333333333333336%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666666666667%; + } + .col-md-push-4 { + left: 33.33333333333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.666666666666664%; + } + .col-md-push-1 { + left: 8.333333333333332%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666666666666%; + } + .col-md-offset-10 { + margin-left: 83.33333333333334%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666666666666%; + } + .col-md-offset-7 { + margin-left: 58.333333333333336%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666666666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.666666666666664%; + } + .col-md-offset-1 { + margin-left: 8.333333333333332%; + } + .col-md-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666666666666%; + } + .col-lg-10 { + width: 83.33333333333334%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666666666666%; + } + .col-lg-7 { + width: 58.333333333333336%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666666666667%; + } + .col-lg-4 { + width: 33.33333333333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.666666666666664%; + } + .col-lg-1 { + width: 8.333333333333332%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666666666666%; + } + .col-lg-pull-10 { + right: 83.33333333333334%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666666666666%; + } + .col-lg-pull-7 { + right: 58.333333333333336%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666666666667%; + } + .col-lg-pull-4 { + right: 33.33333333333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.666666666666664%; + } + .col-lg-pull-1 { + right: 8.333333333333332%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666666666666%; + } + .col-lg-push-10 { + left: 83.33333333333334%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666666666666%; + } + .col-lg-push-7 { + left: 58.333333333333336%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666666666667%; + } + .col-lg-push-4 { + left: 33.33333333333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.666666666666664%; + } + .col-lg-push-1 { + left: 8.333333333333332%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666666666666%; + } + .col-lg-offset-10 { + margin-left: 83.33333333333334%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666666666666%; + } + .col-lg-offset-7 { + margin-left: 58.333333333333336%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666666666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.666666666666664%; + } + .col-lg-offset-1 { + margin-left: 8.333333333333332%; + } + .col-lg-offset-0 { + margin-left: 0%; + } +} +table { + background-color: transparent; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.428571429; + vertical-align: top; + border-top: 1px solid #34302D; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #34302D; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #34302D; +} +.table .table { + background-color: #f1f1f1; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #34302D; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #34302D; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-child(odd) > td, +.table-striped > tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover > td, +.table-hover > tbody > tr:hover > th { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + float: none; + display: table-column; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + float: none; + display: table-cell; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + overflow-x: auto; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #34302D; + -webkit-overflow-scrolling: touch; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + padding: 0; + margin: 0; + border: 0; + min-width: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.428571429; + color: #555555; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.428571429; + color: #555555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.form-control::-moz-placeholder { + color: #777777; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #777777; +} +.form-control::-webkit-input-placeholder { + color: #777777; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #eeeeee; + opacity: 1; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +input[type="date"], +input[type="time"], +input[type="datetime-local"], +input[type="month"] { + line-height: 34px; + line-height: 1.428571429 \0; +} +input[type="date"].input-sm, +input[type="time"].input-sm, +input[type="datetime-local"].input-sm, +input[type="month"].input-sm { + line-height: 30px; +} +input[type="date"].input-lg, +input[type="time"].input-lg, +input[type="datetime-local"].input-lg, +input[type="month"].input-lg { + line-height: 46px; +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + min-height: 20px; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-left: -20px; + margin-top: 4px \9; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-left: 0; + padding-right: 0; +} +.input-sm, +.form-horizontal .form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.input-lg, +.form-horizontal .form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 0; +} +select.input-lg { + height: 46px; + line-height: 46px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 42.5px; +} +.form-control-feedback { + position: absolute; + top: 25px; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; +} +.input-lg + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; +} +.input-sm + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + border-color: #3c763d; + background-color: #dff0d8; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + border-color: #8a6d3b; + background-color: #fcf8e3; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + border-color: #a94442; + background-color: #f2dede; +} +.has-error .form-control-feedback { + color: #a94442; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #ffffff; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + margin-top: 0; + margin-bottom: 0; + padding-top: 7px; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-left: -15px; + margin-right: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + margin-bottom: 0; + padding-top: 7px; + } +} +.form-horizontal .has-feedback .form-control-feedback { + top: 0; + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 14.3px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + } +} +.btn { + display: inline-block; + margin-bottom: 0; + font-weight: normal; + text-align: center; + vertical-align: middle; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 6px 12px; + font-size: 14px; + line-height: 1.428571429; + border-radius: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus { + color: #f1f1f1; + text-decoration: none; +} +.btn:active, +.btn.active { + outline: 0; + background-image: none; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + pointer-events: none; + opacity: .65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-default { + color: #f1f1f1; + background-color: #34302D; + border-color: #6db33f; +} +.btn-default:hover, +.btn-default:focus, +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #f1f1f1; + background-color: #191715; + border-color: #51862f; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #34302D; + border-color: #6db33f; +} +.btn-default .badge { + color: #34302D; + background-color: #f1f1f1; +} +.btn-primary { + color: #fff; + background-color: #428bca; + border-color: #357ebd; +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #fff; + background-color: #3071a9; + border-color: #285e8e; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #428bca; + border-color: #357ebd; +} +.btn-primary .badge { + color: #428bca; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + color: #5fa134; + font-weight: normal; + cursor: pointer; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #5fa134; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #777777; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 0; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height .35s ease; + -o-transition: height .35s ease; + transition: height .35s ease; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + font-size: 14px; + text-align: left; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.428571429; + color: #333333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + text-decoration: none; + color: #262626; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + outline: 0; + background-color: #428bca; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #777777; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: not-allowed; +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + left: auto; + right: 0; +} +.dropdown-menu-left { + left: 0; + right: auto; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.428571429; + color: #777777; + white-space: nowrap; +} +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid; + content: ""; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + left: auto; + right: 0; + } + .navbar-right .dropdown-menu-left { + left: 0; + right: auto; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus { + outline: 0; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child > .btn:last-child, +.btn-group > .btn-group:first-child > .dropdown-toggle { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn-group:last-child > .btn:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-bottom-left-radius: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + float: none; + display: table-cell; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn > input[type="radio"], +[data-toggle="buttons"] > .btn > input[type="checkbox"] { + position: absolute; + z-index: -1; + opacity: 0; + filter: alpha(opacity=0); +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-left: 0; + padding-right: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 0; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 0; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #555555; + text-align: center; + background-color: #eeeeee; + border: 1px solid #ccc; + border-radius: 0; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 0; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 0; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + margin-left: -1px; +} +.nav { + margin-bottom: 0; + padding-left: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} +.nav > li.disabled > a { + color: #777777; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #777777; + text-decoration: none; + background-color: transparent; + cursor: not-allowed; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eeeeee; + border-color: #5fa134; +} +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #34302D; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.428571429; + border: 1px solid transparent; + border-radius: 0 0 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eeeeee #eeeeee #34302D; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #f1f1f1; + background-color: #34302D; + border: 1px solid #34302D; + border-bottom-color: transparent; + cursor: default; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 0; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 0 0 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #f1f1f1; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 0; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #fff; + background-color: #428bca; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 0; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 0 0 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #f1f1f1; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 0; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + overflow-x: visible; + padding-right: 15px; + padding-left: 15px; + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-left: 0; + padding-right: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; + height: 50px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + margin-right: 15px; + padding: 9px 10px; + margin-top: 8px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 0; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 7.5px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } + .navbar-nav.navbar-right:last-child { + margin-right: -15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + } +} +.navbar-form { + margin-left: -15px; + margin-right: -15px; + padding: 10px 15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + margin-top: 8px; + margin-bottom: 8px; +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + border: 0; + margin-left: 0; + margin-right: 0; + padding-top: 0; + padding-bottom: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-form.navbar-right:last-child { + margin-right: -15px; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} +.navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-left: 15px; + margin-right: 15px; + } + .navbar-text.navbar-right:last-child { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #f1f1f1; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #d8d8d8; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777; +} +.navbar-default .navbar-nav > li > a { + color: #f1f1f1; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #f1f1f1; + background-color: #6db33f; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #f1f1f1; + background-color: #6db33f; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #ddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: transparent; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #f1f1f1; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: #6db33f; + color: #f1f1f1; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #f1f1f1; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #f1f1f1; + background-color: #6db33f; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #f1f1f1; + background-color: #6db33f; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #f1f1f1; +} +.navbar-default .navbar-link:hover { + color: #f1f1f1; +} +.navbar-default .btn-link { + color: #f1f1f1; +} +.navbar-default .btn-link:hover, +.navbar-default .btn-link:focus { + color: #f1f1f1; +} +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:hover, +.navbar-default .btn-link[disabled]:focus, +fieldset[disabled] .navbar-default .btn-link:focus { + color: #ccc; +} +.navbar-inverse { + background-color: #222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #777777; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #777777; +} +.navbar-inverse .navbar-nav > li > a { + color: #777777; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + background-color: #080808; + color: #fff; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #777777; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #777777; +} +.navbar-inverse .navbar-link:hover { + color: #fff; +} +.navbar-inverse .btn-link { + color: #777777; +} +.navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link:focus { + color: #fff; +} +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link[disabled]:focus, +fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #444; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 0; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + content: "/\00a0"; + padding: 0 5px; + color: #ccc; +} +.breadcrumb > .active { + color: #777777; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 0; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + line-height: 1.428571429; + text-decoration: none; + color: #5fa134; + background-color: #fff; + border: 1px solid #ddd; + margin-left: -1px; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + color: #5fa134; + background-color: #eeeeee; + border-color: #ddd; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 2; + color: #fff; + background-color: #428bca; + border-color: #428bca; + cursor: default; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #777777; + background-color: #fff; + border-color: #ddd; + cursor: not-allowed; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.pager { + padding-left: 0; + margin: 20px 0; + list-style: none; + text-align: center; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #777777; + background-color: #fff; + cursor: not-allowed; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +a.label:hover, +a.label:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #777777; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #5e5e5e; +} +.label-primary { + background-color: #428bca; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #3071a9; +} +.label-success { + background-color: #5cb85c; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + color: #fff; + line-height: 1; + vertical-align: baseline; + white-space: nowrap; + text-align: center; + background-color: #777777; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +a.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #5fa134; + background-color: #fff; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #eeeeee; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 21px; + font-weight: 200; +} +.jumbotron > hr { + border-top-color: #d5d5d5; +} +.container .jumbotron { + border-radius: 0; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron { + padding-left: 60px; + padding-right: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 63px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 20px; + line-height: 1.428571429; + background-color: #f1f1f1; + border: 1px solid #ddd; + border-radius: 0; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-left: auto; + margin-right: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #5fa134; +} +.thumbnail .caption { + padding: 9px; + color: #f1f1f1; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 0; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #3c763d; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #31708f; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + background-color: #fcf8e3; + border-color: #faebcc; + color: #8a6d3b; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + background-color: #f2dede; + border-color: #ebccd1; + color: #a94442; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-radius: 0; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} +.progress-bar { + float: left; + width: 0%; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #428bca; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-transition: width .6s ease; + -o-transition: width .6s ease; + transition: width .6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar[aria-valuenow="1"], +.progress-bar[aria-valuenow="2"] { + min-width: 30px; +} +.progress-bar[aria-valuenow="0"] { + color: #777777; + min-width: 30px; + background-color: transparent; + background-image: none; + box-shadow: none; +} +.progress-bar-success { + background-color: #5cb85c; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.media, +.media-body { + overflow: hidden; + zoom: 1; +} +.media, +.media .media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media-object { + display: block; +} +.media-heading { + margin: 0 0 5px; +} +.media > .pull-left { + margin-right: 10px; +} +.media > .pull-right { + margin-left: 10px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + margin-bottom: 20px; + padding-left: 0; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} +.list-group-item:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +a.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, +a.list-group-item:focus { + text-decoration: none; + color: #555; + background-color: #f5f5f5; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + background-color: #eeeeee; + color: #777777; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #777777; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #428bca; + border-color: #428bca; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #e1edf7; +} +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} +a.list-group-item-success { + color: #3c763d; +} +a.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +a.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +a.list-group-item-success.active:hover, +a.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} +a.list-group-item-info { + color: #31708f; +} +a.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +a.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +a.list-group-item-info.active:hover, +a.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} +a.list-group-item-warning { + color: #8a6d3b; +} +a.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +a.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} +a.list-group-item-danger { + color: #a94442; +} +a.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +a.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus { + color: #fff; + background-color: #a94442; + border-color: #a94442; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 0; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-right-radius: -1; + border-top-left-radius: -1; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: -1; + border-bottom-left-radius: -1; +} +.panel > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-right-radius: -1; + border-top-left-radius: -1; +} +.panel > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: -1; + border-bottom-left-radius: -1; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-right-radius: -1; + border-top-left-radius: -1; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: -1; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: -1; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: -1; + border-bottom-left-radius: -1; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: -1; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: -1; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive { + border-top: 1px solid #34302D; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + border: 0; + margin-bottom: 0; +} +.panel-group { + margin-bottom: 20px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 0; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse > .panel-body { + border-top: 1px solid #ddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #ddd; +} +.panel-default { + border-color: #ddd; +} +.panel-default > .panel-heading { + color: #333333; + background-color: #f5f5f5; + border-color: #ddd; +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ddd; +} +.panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333333; +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ddd; +} +.panel-primary { + border-color: #428bca; +} +.panel-primary > .panel-heading { + color: #fff; + background-color: #428bca; + border-color: #428bca; +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #428bca; +} +.panel-primary > .panel-heading .badge { + color: #428bca; + background-color: #fff; +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #428bca; +} +.panel-success { + border-color: #d6e9c6; +} +.panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #d6e9c6; +} +.panel-success > .panel-heading .badge { + color: #dff0d8; + background-color: #3c763d; +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #d6e9c6; +} +.panel-info { + border-color: #bce8f1; +} +.panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #bce8f1; +} +.panel-info > .panel-heading .badge { + color: #d9edf7; + background-color: #31708f; +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #bce8f1; +} +.panel-warning { + border-color: #faebcc; +} +.panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #faebcc; +} +.panel-warning > .panel-heading .badge { + color: #fcf8e3; + background-color: #8a6d3b; +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #faebcc; +} +.panel-danger { + border-color: #ebccd1; +} +.panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ebccd1; +} +.panel-danger > .panel-heading .badge { + color: #f2dede; + background-color: #a94442; +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ebccd1; +} +.embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object { + position: absolute; + top: 0; + left: 0; + bottom: 0; + height: 100%; + width: 100%; + border: 0; +} +.embed-responsive.embed-responsive-16by9 { + padding-bottom: 56.25%; +} +.embed-responsive.embed-responsive-4by3 { + padding-bottom: 75%; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-lg { + padding: 24px; + border-radius: 0; +} +.well-sm { + padding: 9px; + border-radius: 0; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: .2; + filter: alpha(opacity=20); +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + opacity: .5; + filter: alpha(opacity=50); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.modal-open { + overflow: hidden; +} +.modal { + display: none; + overflow: hidden; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transform: translate3d(0, -25%, 0); + transform: translate3d(0, -25%, 0); + -webkit-transition: -webkit-transform 0.3s ease-out; + -moz-transition: -moz-transform 0.3s ease-out; + -o-transition: -o-transform 0.3s ease-out; + transition: transform 0.3s ease-out; +} +.modal.in .modal-dialog { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + background-clip: padding-box; + outline: 0; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + opacity: 0; + filter: alpha(opacity=0); +} +.modal-backdrop.in { + opacity: .5; + filter: alpha(opacity=50); +} +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; + min-height: 16.428571429px; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.428571429; +} +.modal-body { + position: relative; + padding: 15px; +} +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + visibility: visible; + font-size: 12px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: .9; + filter: alpha(opacity=90); +} +.tooltip.top { + margin-top: -3px; + padding: 5px 0; +} +.tooltip.right { + margin-left: 3px; + padding: 0 5px; +} +.tooltip.bottom { + margin-top: 3px; + padding: 5px 0; +} +.tooltip.left { + margin-left: -3px; + padding: 0 5px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #000; + border-radius: 0; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-left .tooltip-arrow { + bottom: 0; + left: 5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-right .tooltip-arrow { + bottom: 0; + right: 5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + left: 5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + right: 5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + white-space: normal; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: -1 -1 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + border-width: 10px; + content: ""; +} +.popover.top > .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999999; + border-top-color: rgba(0, 0, 0, 0.25); + bottom: -11px; +} +.popover.top > .arrow:after { + content: " "; + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #fff; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999999; + border-right-color: rgba(0, 0, 0, 0.25); +} +.popover.right > .arrow:after { + content: " "; + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #fff; +} +.popover.bottom > .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999999; + border-bottom-color: rgba(0, 0, 0, 0.25); + top: -11px; +} +.popover.bottom > .arrow:after { + content: " "; + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #fff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999999; + border-left-color: rgba(0, 0, 0, 0.25); +} +.popover.left > .arrow:after { + content: " "; + right: 1px; + border-right-width: 0; + border-left-color: #fff; + bottom: -10px; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + overflow: hidden; + width: 100%; +} +.carousel-inner > .item { + display: none; + position: relative; + -webkit-transition: .6s ease-in-out left; + -o-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + line-height: 1; +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 15%; + opacity: .5; + filter: alpha(opacity=50); + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); +} +.carousel-control.right { + left: auto; + right: 0; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); +} +.carousel-control:hover, +.carousel-control:focus { + outline: 0; + color: #fff; + text-decoration: none; + opacity: .9; + filter: alpha(opacity=90); +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + font-family: serif; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + margin-left: -30%; + padding-left: 0; + list-style: none; + text-align: center; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + border: 1px solid #fff; + border-radius: 10px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); +} +.carousel-indicators .active { + margin: 0; + width: 12px; + height: 12px; + background-color: #fff; +} +.carousel-caption { + position: absolute; + left: 15%; + right: 15%; + bottom: 20px; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -15px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -15px; + } + .carousel-caption { + left: 20%; + right: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-footer:before, +.modal-footer:after { + content: " "; + display: table; +} +.clearfix:after, +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-left: auto; + margin-right: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; + visibility: hidden !important; +} +.affix { + position: fixed; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +@font-face { + font-family: 'varela_roundregular'; + src: url('../fonts/varela_round-webfont.eot'); + src: url('../fonts/varela_round-webfont.eot?#iefix') format('embedded-opentype'), url('../fonts/varela_round-webfont.woff') format('woff'), url('../fonts/varela_round-webfont.ttf') format('truetype'), url('../fonts/varela_round-webfont.svg#varela_roundregular') format('svg'); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: 'montserratregular'; + src: url('../fonts/montserrat-webfont.eot'); + src: url('../fonts/montserrat-webfont.eot?#iefix') format('embedded-opentype'), url('../fonts/montserrat-webfont.woff') format('woff'), url('../fonts/montserrat-webfont.ttf') format('truetype'), url('../fonts/montserrat-webfont.svg#montserratregular') format('svg'); + font-weight: normal; + font-style: normal; +} +body, +h1, +h2, +h3, +p, +input { + margin: 0; + font-weight: 400; + font-family: "varela_roundregular", sans-serif; + color: #34302d; +} +h1 { + font-size: 24px; + line-height: 30px; + font-family: "montserratregular", sans-serif; +} +h2 { + font-size: 18px; + font-weight: 700; + line-height: 24px; + margin-bottom: 10px; + font-family: "montserratregular", sans-serif; +} +h3 { + font-size: 16px; + line-height: 24px; + margin-bottom: 10px; + font-weight: 700; +} +strong { + font-weight: 700; + font-family: "montserratregular", sans-serif; +} +.navbar { + border-top: 4px solid #6db33f; + background-color: #34302d; + margin-bottom: 0px; + border-bottom: 0; + border-left: 0; + border-right: 0; +} +.navbar a.navbar-brand { + background: url("../images/spring-logo-eureka.png") -1px -1px no-repeat; + margin: 12px 0 6px; + width: 300px; + height: 46px; + display: inline-block; + text-decoration: none; + padding: 0; +} +.navbar a.navbar-brand span { + display: block; + width: 300px; + height: 46px; + background: url("../images/spring-logo-eureka.png") -1px -48px no-repeat; + opacity: 0; + -moz-transition: opacity 0.12s ease-in-out; + -webkit-transition: opacity 0.12s ease-in-out; + -o-transition: opacity 0.12s ease-in-out; +} +.navbar a:hover.navbar-brand span { + opacity: 1; +} +.navbar li > a, +.navbar-text { + font-family: "montserratregular", sans-serif; + text-shadow: none; + font-size: 14px; + padding: 28px 20px; + transition: all 0.15s; + -webkit-transition: all 0.15s; + -moz-transition: all 0.15s; + -o-transition: all 0.15s; + -ms-transition: all 0.15s; +} +.navbar li > a { + text-transform: uppercase; +} +.navbar .navbar-text { + margin-top: 0; + margin-bottom: 0; +} +.navbar li:hover > a { + color: #eeeeee; + background-color: #6db33f; +} +.navbar-toggle { + border-width: 0; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 3px; +} +.navbar-toggle .icon-bar { + width: 19px; + height: 3px; +} +@media (max-width: 768px) { + .navbar-toggle { + position: absolute; + z-index: 9999; + left: 0px; + top: 0px; + } + .navbar a.navbar-brand { + display: block; + margin: 0 auto 0 auto; + width: 200px; + height: 50px; + float: none; + background: url("../images/spring-logo-eureka-mobile.png") 0 center no-repeat; + } + .homepage-billboard .homepage-subtitle { + font-size: 21px; + line-height: 21px; + } + .navbar a.navbar-brand span { + display: none; + } + .navbar { + border-top-width: 0; + } + .xd-container { + margin-top: 20px; + margin-bottom: 30px; + } + .index-page--subtitle { + margin-top: 10px; + margin-bottom: 30px; + } +} +.table > thead > tr > th { + background-color: #3c3834; + color: #f1f1f1; +} +.table-filter { + background-color: #34302D; + padding: 9px 12px; +} +.nav > li > a { + color: #838789; +} +.btn-default { + border-width: 2px; + transition: border 0.15s; + -webkit-transition: border 0.15s; + -moz-transition: border 0.15s; + -o-transition: border 0.15s; + -ms-transition: border 0.15s; +} +.btn-default:hover, +.btn-default:focus, +.btn-default:active, +.btn-default.active, +.open .dropdown-toggle.btn-default { + background-color: #34302D; + border-color: #34302D; +} +.container .text-muted { + margin: 20px 0; +} +code { + font-size: 80%; +} +.xd-container { + margin-top: 40px; + margin-bottom: 100px; +} +h1 { + margin-bottom: 15px; +} +.index-page--subtitle { + font-size: 16px; + line-height: 24px; + margin: 0 0 30px; +} +.form-horizontal button.btn-inverse { + margin-left: 32px; +} +#job-params-modal .modal-dialog { + width: 90%; + margin-left: auto; + margin-right: auto; +} +[ng-cloak].splash { + display: block !important; +} +[ng-cloak] { + display: none; +} +.splash { + background: #6db33f; + color: #34302D; + display: none; +} +.error-page { + margin-top: 100px; + text-align: center; +} +.error-page .error-title { + font-size: 24px; + line-height: 24px; + margin: 30px 0 0; +} +table td { + vertical-align: middle !important; +} +table td .progress { + margin-bottom: 0; +} +table td.action-column { + width: 1px; +} +.help-block { + color: #f1f1f1; +} diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/montserrat-webfont.eot b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/montserrat-webfont.eot new file mode 100644 index 0000000000..0caea9169a Binary files /dev/null and b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/montserrat-webfont.eot differ diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/montserrat-webfont.svg b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/montserrat-webfont.svg new file mode 100644 index 0000000000..7bd96bdfdc --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/montserrat-webfont.svg @@ -0,0 +1,1283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/montserrat-webfont.ttf b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/montserrat-webfont.ttf new file mode 100644 index 0000000000..9953fe62e0 Binary files /dev/null and b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/montserrat-webfont.ttf differ diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/montserrat-webfont.woff b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/montserrat-webfont.woff new file mode 100644 index 0000000000..eb49333f71 Binary files /dev/null and b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/montserrat-webfont.woff differ diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/varela_round-webfont.eot b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/varela_round-webfont.eot new file mode 100644 index 0000000000..dfee0c26e7 Binary files /dev/null and b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/varela_round-webfont.eot differ diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/varela_round-webfont.svg b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/varela_round-webfont.svg new file mode 100644 index 0000000000..3280e2c43c --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/varela_round-webfont.svg @@ -0,0 +1,7875 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/varela_round-webfont.ttf b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/varela_round-webfont.ttf new file mode 100644 index 0000000000..3ca0666937 Binary files /dev/null and b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/varela_round-webfont.ttf differ diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/varela_round-webfont.woff b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/varela_round-webfont.woff new file mode 100644 index 0000000000..77ba16614b Binary files /dev/null and b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/fonts/varela_round-webfont.woff differ diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/404-icon.png b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/404-icon.png new file mode 100644 index 0000000000..912f456bfc Binary files /dev/null and b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/404-icon.png differ diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/homepage-bg.jpg b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/homepage-bg.jpg new file mode 100644 index 0000000000..0318437663 Binary files /dev/null and b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/homepage-bg.jpg differ diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/platform-bg.png b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/platform-bg.png new file mode 100644 index 0000000000..512185839b Binary files /dev/null and b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/platform-bg.png differ diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/platform-spring-xd.png b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/platform-spring-xd.png new file mode 100644 index 0000000000..0cb2662d7b Binary files /dev/null and b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/platform-spring-xd.png differ diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/spring-logo-eureka-mobile.png b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/spring-logo-eureka-mobile.png new file mode 100644 index 0000000000..fc59a236b1 Binary files /dev/null and b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/spring-logo-eureka-mobile.png differ diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/spring-logo-eureka.png b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/spring-logo-eureka.png new file mode 100644 index 0000000000..b22de1f2a9 Binary files /dev/null and b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/images/spring-logo-eureka.png differ diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/js/wro.js b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/js/wro.js new file mode 100644 index 0000000000..c3ae5c5f37 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/static/eureka/js/wro.js @@ -0,0 +1,2 @@ + +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.1",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+Math.random()}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("