Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
44f61fcdfc
27
jee7/pom.xml
27
jee7/pom.xml
@ -98,7 +98,16 @@
|
||||
<artifactId>shrinkwrap-resolver-impl-maven-archive</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.faces</groupId>
|
||||
<artifactId>jsf-api</artifactId>
|
||||
@ -378,5 +387,21 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>webdriver-chrome</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<browser>chrome</browser>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>webdriver-firefox</id>
|
||||
<properties>
|
||||
<browser>firefox</browser>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
@ -8,7 +8,7 @@
|
||||
</h:head>
|
||||
<h:body>
|
||||
<h1>Testing converters</h1>
|
||||
<h:form id="myform">
|
||||
<h:form id="myForm">
|
||||
<h:outputLabel value="Age:"/>
|
||||
<h:inputText id="age" value="#{convListVal.age}">
|
||||
<f:converter converterId="javax.faces.Integer" />
|
||||
@ -19,13 +19,13 @@
|
||||
<h:inputText id="average" value="#{convListVal.average}">
|
||||
<f:converter converterId="javax.faces.Double" />
|
||||
</h:inputText>
|
||||
<h:message for="average" />
|
||||
<h:message id = "averageError" for="average" />
|
||||
<br/>
|
||||
<h:outputLabel value="Date:"/>
|
||||
<h:inputText id="MyDate" value="#{convListVal.myDate}">
|
||||
<h:inputText id="myDate" value="#{convListVal.myDate}">
|
||||
<f:convertDateTime pattern="dd/MM/yyyy" />
|
||||
</h:inputText>
|
||||
<h:message for="MyDate" />
|
||||
<h:message id="myDateError" for="myDate" />
|
||||
<br/>
|
||||
<h:outputText value="#{convListVal.myDate}">
|
||||
<f:convertDateTime dateStyle="full" locale="en"/>
|
||||
@ -41,7 +41,7 @@
|
||||
<h:inputText id="surname" value="#{convListVal.surname}">
|
||||
<f:validateLength minimum="5" maximum="10"/>
|
||||
</h:inputText>
|
||||
<h:message for="surname" errorStyle="color:red" />
|
||||
<h:message id="surnameError" for="surname" errorStyle="color:red" />
|
||||
</h:panelGroup>
|
||||
<br/>
|
||||
<h:commandButton id="send" value="submit" type="submit" />
|
||||
|
13
jee7/src/main/webapp/WEB-INF/faces-config.xml
Normal file
13
jee7/src/main/webapp/WEB-INF/faces-config.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faces-config
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
|
||||
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
|
||||
version="2.0">
|
||||
<managed-bean>
|
||||
<managed-bean-name>convListVal</managed-bean-name>
|
||||
<managed-bean-class>com.baeldung.convListVal.ConvListVal</managed-bean-class>
|
||||
<managed-bean-scope>session</managed-bean-scope>
|
||||
</managed-bean>
|
||||
</faces-config>
|
41
jee7/src/main/webapp/WEB-INF/web.xml
Normal file
41
jee7/src/main/webapp/WEB-INF/web.xml
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
|
||||
<!-- The bare minimum needed for JSF 2.2 is a servlet 2.5 or later
|
||||
declaration (this uses 3.0) and the mapping for the FacesServlet.
|
||||
Setting PROJECT_STAGE to Development is highly recommended
|
||||
during initial development so that you get more helpful
|
||||
error messages. Whether you want server-side state saving
|
||||
(default) or client-side is a more complicated question:
|
||||
client-side uses more bandwidth but fewer server resources.
|
||||
Client-side also helps to avoid the dreaded view expired exceptions.
|
||||
|
||||
From JSF 2 and PrimeFaces tutorial
|
||||
at http://www.coreservlets.com/JSF-Tutorial/jsf2/
|
||||
-->
|
||||
<servlet>
|
||||
<servlet-name>Faces Servlet</servlet-name>
|
||||
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>Faces Servlet</servlet-name>
|
||||
<url-pattern>*.jsf</url-pattern>
|
||||
</servlet-mapping>
|
||||
<context-param>
|
||||
<param-name>javax.faces.PROJECT_STAGE</param-name>
|
||||
<param-value>Development</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<description>State saving method: 'client' or 'server' (default). See JSF Specification section 2.5.2</description>
|
||||
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
|
||||
<param-value>client</param-value>
|
||||
</context-param>
|
||||
<!-- If you go to http://host/project/ (with no file name), it will
|
||||
try index.jsf first, welcome.jsf next, and so forth.
|
||||
-->
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.jsf</welcome-file>
|
||||
<welcome-file>welcome.jsf</welcome-file>
|
||||
<welcome-file>index.html</welcome-file>
|
||||
<welcome-file>index.jsp</welcome-file>
|
||||
</welcome-file-list>
|
||||
</web-app>
|
101
jee7/src/test/java/com/baeldung/convListVal/ConvListValTest.java
Normal file
101
jee7/src/test/java/com/baeldung/convListVal/ConvListValTest.java
Normal file
@ -0,0 +1,101 @@
|
||||
package com.baeldung.convListVal;
|
||||
|
||||
import static org.jboss.arquillian.graphene.Graphene.guardHttp;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
|
||||
import org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.container.test.api.RunAsClient;
|
||||
import org.jboss.arquillian.drone.api.annotation.Drone;
|
||||
import org.jboss.arquillian.junit.Arquillian;
|
||||
import org.jboss.arquillian.test.api.ArquillianResource;
|
||||
import org.jboss.shrinkwrap.api.ShrinkWrap;
|
||||
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
|
||||
@RunWith(Arquillian.class)
|
||||
public class ConvListValTest {
|
||||
|
||||
@ArquillianResource
|
||||
private URL deploymentUrl;
|
||||
|
||||
private static final String WEBAPP_SRC = "src/main/webapp";
|
||||
|
||||
@Deployment(testable = false)
|
||||
public static WebArchive createDeployment() {
|
||||
return ( ShrinkWrap.create(
|
||||
WebArchive.class, "jee7.war").
|
||||
addClasses(ConvListVal.class, MyListener.class)).
|
||||
addAsWebResource(new File(WEBAPP_SRC, "ConvListVal.xhtml")).
|
||||
addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
|
||||
}
|
||||
|
||||
@Drone
|
||||
WebDriver browser;
|
||||
|
||||
@ArquillianResource
|
||||
URL contextPath;
|
||||
|
||||
@FindBy(id="myForm:age")
|
||||
private WebElement ageInput;
|
||||
|
||||
@FindBy(id="myForm:average")
|
||||
private WebElement averageInput;
|
||||
|
||||
@FindBy(id="myForm:send")
|
||||
private WebElement sendButton;
|
||||
|
||||
@Test
|
||||
@RunAsClient
|
||||
public void givenAge_whenAgeInvalid_thenErrorMessage() throws Exception {
|
||||
browser.get(deploymentUrl.toExternalForm() + "ConvListVal.jsf");
|
||||
ageInput.sendKeys("stringage");
|
||||
guardHttp(sendButton).click();
|
||||
Assert.assertTrue("Show Age error message", browser.findElements(By.id("myForm:ageError")).size() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RunAsClient
|
||||
public void givenAverage_whenAverageInvalid_thenErrorMessage() throws Exception {
|
||||
browser.get(deploymentUrl.toExternalForm() + "ConvListVal.jsf");
|
||||
averageInput.sendKeys("stringaverage");
|
||||
guardHttp(sendButton).click();
|
||||
Assert.assertTrue("Show Average error message", browser.findElements(By.id("myForm:averageError")).size() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RunAsClient
|
||||
public void givenDate_whenDateInvalid_thenErrorMessage() throws Exception {
|
||||
browser.get(deploymentUrl.toExternalForm() + "ConvListVal.jsf");
|
||||
averageInput.sendKeys("123");
|
||||
guardHttp(sendButton).click();
|
||||
Assert.assertTrue("Show Date error message", browser.findElements(By.id("myForm:myDateError")).size() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RunAsClient
|
||||
public void givenSurname_whenSurnameMinLenghtInvalid_thenErrorMessage() throws Exception {
|
||||
browser.get(deploymentUrl.toExternalForm() + "ConvListVal.jsf");
|
||||
averageInput.sendKeys("aaa");
|
||||
guardHttp(sendButton).click();
|
||||
Assert.assertTrue("Show Surname error message", browser.findElements(By.id("myForm:surnameError")).size() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RunAsClient
|
||||
public void givenSurname_whenSurnameMaxLenghtInvalid_thenErrorMessage() throws Exception {
|
||||
browser.get(deploymentUrl.toExternalForm() + "ConvListVal.jsf");
|
||||
averageInput.sendKeys("aaaaabbbbbc");
|
||||
guardHttp(sendButton).click();
|
||||
Assert.assertTrue("Show Surname error message", browser.findElements(By.id("myForm:surnameError")).size() > 0);
|
||||
}
|
||||
|
||||
}
|
@ -22,7 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
public class WordCountIntegrationTest {
|
||||
final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
|
||||
private final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
|
||||
|
||||
@Test
|
||||
public void givenDataSet_whenExecuteWordCount_thenReturnWordCount() throws Exception {
|
||||
@ -65,8 +65,8 @@ public class WordCountIntegrationTest {
|
||||
List<Integer> ages = personDataSource.map(p -> p.age).collect();
|
||||
|
||||
//then
|
||||
assertThat(ages.size()).isEqualTo(2);
|
||||
assertThat(ages.containsAll(Arrays.asList(23, 75))).isTrue();
|
||||
assertThat(ages).hasSize(2);
|
||||
assertThat(ages).contains(23, 75);
|
||||
|
||||
}
|
||||
|
||||
@ -110,8 +110,8 @@ public class WordCountIntegrationTest {
|
||||
.collect();
|
||||
|
||||
//then
|
||||
assertThat(joined.size()).isEqualTo(1);
|
||||
assertThat(joined.contains(new Tuple2<>(firstTransaction, address)));
|
||||
assertThat(joined).hasSize(1);
|
||||
assertThat(joined).contains(new Tuple2<>(firstTransaction, address));
|
||||
|
||||
}
|
||||
|
||||
|
34
mybatis/pom.xml
Normal file
34
mybatis/pom.xml
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<properties>
|
||||
<junit.version>4.12</junit.version>
|
||||
<derby.version>10.13.1.1</derby.version>
|
||||
<mybatis.version>3.2.2</mybatis.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
<artifactId>derby</artifactId>
|
||||
<version>${derby.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
<version>${mybatis.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,24 @@
|
||||
package com.baeldung.mybatis.mapper;
|
||||
|
||||
import com.baeldung.mybatis.model.Address;
|
||||
import com.baeldung.mybatis.model.Person;
|
||||
import org.apache.ibatis.annotations.*;
|
||||
|
||||
|
||||
public interface AddressMapper {
|
||||
|
||||
@Insert("Insert into address (streetAddress,personId) values(#{streetAddress},#{personId})")
|
||||
@Options(useGeneratedKeys = true,flushCache=true )
|
||||
public Integer saveAddress(Address address);
|
||||
|
||||
@Select("SELECT addressId, streetAddress FROM Address WHERE addressId = #{addressId}")
|
||||
@Results(value = {
|
||||
@Result(property = "addressId", column = "addressId"),
|
||||
@Result(property = "streetAddress", column = "streetAddress"),
|
||||
@Result(property = "person", column = "personId",javaType =Person.class,one=@One(select = "getPerson"))
|
||||
})
|
||||
Address getAddresses(Integer addressID);
|
||||
|
||||
@Select("SELECT personId FROM address WHERE addressId = #{addressId})")
|
||||
Person getPerson(Integer personId);
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package com.baeldung.mybatis.mapper;
|
||||
|
||||
import com.baeldung.mybatis.model.Address;
|
||||
import com.baeldung.mybatis.model.Person;
|
||||
import com.baeldung.mybatis.utils.MyBatisUtil;
|
||||
import org.apache.ibatis.annotations.*;
|
||||
import org.apache.ibatis.mapping.StatementType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public interface PersonMapper {
|
||||
|
||||
@Insert("Insert into person(name) values (#{name})")
|
||||
public Integer save(Person person);
|
||||
|
||||
@Update("Update Person set name= #{name} where personId=#{personId}")
|
||||
public void updatePerson(Person person);
|
||||
|
||||
@Delete("Delete from Person where personId=#{personId}")
|
||||
public void deletePersonById(Integer personId);
|
||||
|
||||
@Select("SELECT person.personId, person.name FROM person WHERE person.personId = #{personId}")
|
||||
Person getPerson(Integer personId);
|
||||
|
||||
@Select("Select personId,name from Person where personId=#{personId}")
|
||||
@Results(value ={
|
||||
@Result(property = "personId", column = "personId"),
|
||||
@Result(property="name", column = "name"),
|
||||
@Result(property = "addresses",javaType = List.class,column = "personId",
|
||||
many=@Many(select = "getAddresses"))
|
||||
|
||||
})
|
||||
public Person getPersonById(Integer personId);
|
||||
|
||||
@Select("select addressId,streetAddress,personId from address where personId=#{personId}")
|
||||
public Address getAddresses(Integer personId);
|
||||
|
||||
@Select("select * from Person ")
|
||||
@MapKey("personId")
|
||||
Map<Integer,Person> getAllPerson();
|
||||
|
||||
@SelectProvider(type=MyBatisUtil.class,method="getPersonByName")
|
||||
public Person getPersonByName(String name);
|
||||
|
||||
|
||||
@Select(value= "{ CALL getPersonByProc( #{personId, mode=IN, jdbcType=INTEGER})}")
|
||||
@Options(statementType = StatementType.CALLABLE)
|
||||
public Person getPersonByProc(Integer personId);
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.baeldung.mybatis.model;
|
||||
|
||||
|
||||
public class Address {
|
||||
|
||||
private Integer addressId;
|
||||
private String streetAddress;
|
||||
private Integer personId;
|
||||
|
||||
public Address() {
|
||||
}
|
||||
|
||||
public Integer getPersonId() {
|
||||
return personId;
|
||||
}
|
||||
|
||||
public void setPersonId(Integer personId) {
|
||||
this.personId = personId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Address(String streetAddress) {
|
||||
this.streetAddress =streetAddress;
|
||||
}
|
||||
|
||||
public Person getPerson() {
|
||||
return person;
|
||||
}
|
||||
|
||||
public void setPerson(Person person) {
|
||||
this.person = person;
|
||||
}
|
||||
|
||||
private Person person;
|
||||
|
||||
public Address(int i, String name) {
|
||||
this.streetAddress = name;
|
||||
}
|
||||
|
||||
public Integer getAddressId() {
|
||||
return addressId;
|
||||
}
|
||||
|
||||
public String getStreetAddress() {
|
||||
return streetAddress;
|
||||
}
|
||||
|
||||
}
|
40
mybatis/src/main/java/com/baeldung/mybatis/model/Person.java
Normal file
40
mybatis/src/main/java/com/baeldung/mybatis/model/Person.java
Normal file
@ -0,0 +1,40 @@
|
||||
package com.baeldung.mybatis.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class Person {
|
||||
|
||||
private Integer personId;
|
||||
private String name;
|
||||
private List<Address> addresses;
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(Integer personId, String name) {
|
||||
this.personId=personId;
|
||||
this.name = name;
|
||||
addresses = new ArrayList<Address>();
|
||||
}
|
||||
|
||||
public Person(String name) {
|
||||
this.name=name;
|
||||
}
|
||||
|
||||
public Integer getPersonId() {
|
||||
return personId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void addAddress(Address address){
|
||||
addresses.add(address);
|
||||
}
|
||||
|
||||
public List<Address> getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.baeldung.mybatis.utils;
|
||||
import org.apache.ibatis.io.Resources;
|
||||
import org.apache.ibatis.jdbc.SQL;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class MyBatisUtil {
|
||||
private static SqlSessionFactory sqlSessionFactory;
|
||||
static {
|
||||
String resource = "mybatis-config.xml";
|
||||
InputStream inputStream;
|
||||
try {
|
||||
inputStream = Resources.getResourceAsStream(resource);
|
||||
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public static SqlSessionFactory getSqlSessionFactory(){
|
||||
return sqlSessionFactory;
|
||||
}
|
||||
|
||||
public String getPersonByName(String name){
|
||||
return new SQL(){{
|
||||
SELECT("*");
|
||||
FROM("person");
|
||||
WHERE("name like #{name} || '%'");
|
||||
}}.toString();
|
||||
}
|
||||
}
|
21
mybatis/src/main/resources/mybatis-config.xml
Normal file
21
mybatis/src/main/resources/mybatis-config.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE configuration
|
||||
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||
<configuration>
|
||||
<environments default="development">
|
||||
<environment id="development">
|
||||
<transactionManager type="JDBC"/>
|
||||
<dataSource type="POOLED">
|
||||
<property name="driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
|
||||
<property name="url" value="jdbc:derby:testdb1;create=true"/>
|
||||
<property name="username" value="sa"/>
|
||||
<property name="password" value="pass123"/>
|
||||
</dataSource>
|
||||
</environment>
|
||||
</environments>
|
||||
<mappers>
|
||||
<mapper class="com.baeldung.mybatis.mapper.PersonMapper"/>
|
||||
<mapper class="com.baeldung.mybatis.mapper.AddressMapper"/>
|
||||
</mappers>
|
||||
</configuration>
|
@ -0,0 +1,149 @@
|
||||
package com.baeldung.mybatis.mapper;
|
||||
|
||||
import com.baeldung.mybatis.model.Address;
|
||||
import com.baeldung.mybatis.model.Person;
|
||||
import com.baeldung.mybatis.utils.MyBatisUtil;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
|
||||
public class PersonMapperTest {
|
||||
|
||||
SqlSession session;
|
||||
|
||||
@Before
|
||||
public void setup() throws SQLException {
|
||||
|
||||
session = MyBatisUtil.getSqlSessionFactory().openSession();
|
||||
createTables(session);
|
||||
|
||||
}
|
||||
|
||||
private void createTables(SqlSession session) throws SQLException {
|
||||
|
||||
String createPersonTable = "create table person ("
|
||||
+ "personId integer not null generated always as"
|
||||
+ " identity (start with 1, increment by 1), "
|
||||
+ "name varchar(30) not null, "
|
||||
+ "constraint primary_key_person primary key (personId))";
|
||||
|
||||
String createAddressTable = "create table address ("
|
||||
+ "addressId integer not null generated always as"
|
||||
+ " identity (start with 1, increment by 1), "
|
||||
+ "streetAddress varchar(300), personId integer, "
|
||||
+ "constraint primary_key_address primary key (addressId))";
|
||||
|
||||
String alterTable="ALTER TABLE " +
|
||||
" address ADD CONSTRAINT fk_person FOREIGN KEY (personId) REFERENCES person (personId)";
|
||||
|
||||
|
||||
session.getConnection().createStatement().execute(createPersonTable);
|
||||
session.getConnection().createStatement().execute(createAddressTable);
|
||||
session.getConnection().createStatement().execute(alterTable);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenPersonAdressSaved_ThenPersonAddressCanBeQueried(){
|
||||
Person person=new Person("Baljeet S");
|
||||
Address address = new Address("Pune");
|
||||
PersonMapper personMapper=session.getMapper(PersonMapper.class);
|
||||
Integer id =personMapper.save(person);
|
||||
address.setPersonId(id);
|
||||
AddressMapper addressMapper=session.getMapper(AddressMapper.class);
|
||||
addressMapper.saveAddress(address);
|
||||
|
||||
Person returnedPerson= personMapper.getPersonById(id);
|
||||
assertEquals("Baljeet S", returnedPerson.getName());
|
||||
assertEquals("Pune", returnedPerson.getAddresses().get(0).getStreetAddress());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenPersonSaved_ThenPersonCanBeQueried(){
|
||||
Person person=new Person("Baljeet S");
|
||||
Address address = new Address("Pune");
|
||||
PersonMapper personMapper=session.getMapper(PersonMapper.class);
|
||||
Integer id =personMapper.save(person);
|
||||
address.setPersonId(id);
|
||||
AddressMapper addressMapper=session.getMapper(AddressMapper.class);
|
||||
addressMapper.saveAddress(address);
|
||||
|
||||
Person returnedPerson= personMapper.getPerson(id);
|
||||
assertEquals("Baljeet S", returnedPerson.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenPersonUpdated_ThenPersonIsChanged(){
|
||||
Person person=new Person("Baljeet S");
|
||||
Address address = new Address("Pune");
|
||||
PersonMapper personMapper=session.getMapper(PersonMapper.class);
|
||||
Integer id =personMapper.save(person);
|
||||
address.setPersonId(id);
|
||||
AddressMapper addressMapper=session.getMapper(AddressMapper.class);
|
||||
addressMapper.saveAddress(address);
|
||||
|
||||
personMapper.updatePerson(new Person(id,"Baljeet1"));
|
||||
Person returnedPerson= personMapper.getPerson(id);
|
||||
assertEquals("Baljeet1", returnedPerson.getName());
|
||||
}
|
||||
@Test
|
||||
public void whenPersoSaved_ThenMapIsReturned(){
|
||||
Person person=new Person("Baljeet S");
|
||||
Address address = new Address("Pune");
|
||||
PersonMapper personMapper=session.getMapper(PersonMapper.class);
|
||||
Integer id =personMapper.save(person);
|
||||
address.setPersonId(id);
|
||||
AddressMapper addressMapper=session.getMapper(AddressMapper.class);
|
||||
addressMapper.saveAddress(address);
|
||||
|
||||
Map<Integer, Person> returnedPerson= personMapper.getAllPerson();
|
||||
assertEquals(1, returnedPerson.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenPersonSearched_ThenResultIsReturned(){
|
||||
Person person=new Person("Baljeet S");
|
||||
Address address = new Address("Pune");
|
||||
PersonMapper personMapper=session.getMapper(PersonMapper.class);
|
||||
Integer id =personMapper.save(person);
|
||||
address.setPersonId(id);
|
||||
AddressMapper addressMapper=session.getMapper(AddressMapper.class);
|
||||
addressMapper.saveAddress(address);
|
||||
|
||||
Person returnedPerson= personMapper.getPersonByName("Baljeet S");
|
||||
assertEquals("Baljeet S", returnedPerson.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAddressSearched_ThenResultIsReturned(){
|
||||
Person person=new Person("Baljeet S");
|
||||
Address address = new Address("Pune");
|
||||
PersonMapper personMapper=session.getMapper(PersonMapper.class);
|
||||
Integer id =personMapper.save(person);
|
||||
address.setPersonId(id);
|
||||
AddressMapper addressMapper=session.getMapper(AddressMapper.class);
|
||||
Integer addressId=addressMapper.saveAddress(address);
|
||||
Address returnedAddress=addressMapper.getAddresses(addressId);
|
||||
|
||||
assertEquals("Pune", returnedAddress.getStreetAddress());
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() throws SQLException {
|
||||
session.getConnection().createStatement().execute("drop table address");
|
||||
session.getConnection().createStatement().execute("drop table person");
|
||||
|
||||
session.close();
|
||||
|
||||
}
|
||||
|
||||
}
|
1
pom.xml
1
pom.xml
@ -215,6 +215,7 @@
|
||||
<module>vertx</module>
|
||||
<module>spring-data-gemfire</module>
|
||||
<module>cucumber</module>
|
||||
<module>mybatis</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
|
@ -0,0 +1,26 @@
|
||||
package com.baeldung.dynamicvalidation;
|
||||
|
||||
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
|
||||
import static java.lang.annotation.ElementType.CONSTRUCTOR;
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
|
||||
@Constraint(validatedBy = { ContactInfoValidator.class })
|
||||
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ContactInfo {
|
||||
String message() default "Invalid value";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.baeldung.dynamicvalidation;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.baeldung.dynamicvalidation.dao.ContactInfoExpressionRepository;
|
||||
import com.baeldung.dynamicvalidation.model.ContactInfoExpression;
|
||||
|
||||
public class ContactInfoValidator implements ConstraintValidator<ContactInfo, String> {
|
||||
|
||||
@Autowired
|
||||
private ContactInfoExpressionRepository expressionRepository;
|
||||
|
||||
@Override
|
||||
public void initialize(final ContactInfo contactInfo) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(final String value, final ConstraintValidatorContext context) {
|
||||
String expressionType = System.getProperty("contactInfoType");
|
||||
System.out.println(expressionType);
|
||||
final ContactInfoExpression expression = expressionRepository.findOne(expressionType);
|
||||
if (expression != null) {
|
||||
final String pattern = expression.getPattern();
|
||||
if (Pattern.matches(pattern, value))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.baeldung.dynamicvalidation;
|
||||
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class DynamicValidationApp {
|
||||
@RolesAllowed("*")
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("security.basic.enabled", "false");
|
||||
SpringApplication.run(DynamicValidationApp.class, args);
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.baeldung.dynamicvalidation.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import com.baeldung.dynamicvalidation.dao.ContactInfoExpressionRepository;
|
||||
import com.baeldung.dynamicvalidation.model.ContactInfoExpression;
|
||||
import com.baeldung.dynamicvalidation.model.Customer;
|
||||
|
||||
@Controller
|
||||
public class CustomerController {
|
||||
|
||||
@Autowired
|
||||
private ContactInfoExpressionRepository expressionRepository;
|
||||
|
||||
@GetMapping("/customer")
|
||||
public String getCustomerPage(Model model) {
|
||||
model.addAttribute("contactInfoType", System.getProperty("contactInfoType"));
|
||||
return "customer";
|
||||
}
|
||||
|
||||
@PostMapping("/customer")
|
||||
public String validateCustomer(@Valid final Customer customer, final BindingResult result, final Model model) {
|
||||
if (result.hasErrors()) {
|
||||
model.addAttribute("message", "The information is invalid!");
|
||||
} else {
|
||||
model.addAttribute("message", "The information is valid!");
|
||||
}
|
||||
model.addAttribute("contactInfoType", System.getProperty("contactInfoType"));
|
||||
return "customer";
|
||||
}
|
||||
|
||||
@PostMapping("/updateContactInfoType")
|
||||
@ResponseBody
|
||||
public void updateContactInfoType(@RequestParam final String type) {
|
||||
System.setProperty("contactInfoType", type);
|
||||
}
|
||||
|
||||
@GetMapping("/contactInfoTypes")
|
||||
@ResponseBody
|
||||
public List<ContactInfoExpression> getContactInfoType(Model model) {
|
||||
return expressionRepository.findAll();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.baeldung.dynamicvalidation.config;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
@EnableJpaRepositories("com.baeldung.dynamicvalidation.dao")
|
||||
@EntityScan("com.baeldung.dynamicvalidation.model")
|
||||
@Configuration
|
||||
public class PersistenceConfig {
|
||||
|
||||
@Bean
|
||||
public JdbcTemplate getJdbcTemplate() {
|
||||
return new JdbcTemplate(dataSource());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
|
||||
EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.H2).addScript("schema-expressions.sql").addScript("data-expressions.sql").build();
|
||||
return db;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.baeldung.dynamicvalidation.dao;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import com.baeldung.dynamicvalidation.model.ContactInfoExpression;
|
||||
|
||||
public interface ContactInfoExpressionRepository extends JpaRepository<ContactInfoExpression, String> {
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.baeldung.dynamicvalidation.model;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class ContactInfoExpression {
|
||||
|
||||
@Id
|
||||
@Column(name = "expression_type")
|
||||
private String type;
|
||||
private String pattern;
|
||||
|
||||
public ContactInfoExpression() {
|
||||
|
||||
}
|
||||
|
||||
public ContactInfoExpression(final String type, final String pattern) {
|
||||
this.type = type;
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
public void setPattern(final String pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.baeldung.dynamicvalidation.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import com.baeldung.dynamicvalidation.ContactInfo;
|
||||
|
||||
@Entity
|
||||
public class Customer {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@ContactInfo
|
||||
private String contactInfo;
|
||||
|
||||
public Customer() {
|
||||
}
|
||||
|
||||
public Customer(final long id, final String contactInfo) {
|
||||
this.id = id;
|
||||
this.contactInfo = contactInfo;
|
||||
}
|
||||
|
||||
public String getContactInfo() {
|
||||
return contactInfo;
|
||||
}
|
||||
|
||||
public void setContactInfo(final String contactInfo) {
|
||||
this.contactInfo = contactInfo;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
3
spring-boot/src/main/resources/data-expressions.sql
Normal file
3
spring-boot/src/main/resources/data-expressions.sql
Normal file
@ -0,0 +1,3 @@
|
||||
insert into contact_info_expression values ('email','[a-z0-9!#$%&*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?')
|
||||
insert into contact_info_expression values ('phone','^([0-9]( |-)?)?(\(?[0-9]{3}\)?|[0-9]{3})( |-)?([0-9]{3}( |-)?[0-9]{4}|[a-zA-Z0-9]{7})$')
|
||||
insert into contact_info_expression values ('website','^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$')
|
5
spring-boot/src/main/resources/schema-expressions.sql
Normal file
5
spring-boot/src/main/resources/schema-expressions.sql
Normal file
@ -0,0 +1,5 @@
|
||||
create table contact_info_expression(
|
||||
expression_type varchar(50) not null,
|
||||
pattern varchar(500) not null,
|
||||
PRIMARY KEY ( expression_type )
|
||||
);
|
41
spring-boot/src/main/resources/templates/customer.html
Normal file
41
spring-boot/src/main/resources/templates/customer.html
Normal file
@ -0,0 +1,41 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
|
||||
<title>Customer Page</title>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$.ajax({
|
||||
url: "contactInfoTypes"
|
||||
}).done(function(data) {
|
||||
var contactInfoType = $('#contactInfoType').text();
|
||||
$.each(data,function(key, value) {
|
||||
var o = new Option(value.type, value.type);
|
||||
if (value.type == contactInfoType) {
|
||||
o.selected = true;
|
||||
}
|
||||
$('#expressions').append(o);
|
||||
});
|
||||
});
|
||||
$('#expressions').change(function(){
|
||||
$.ajax({
|
||||
url: "updateContactInfoType",
|
||||
method:'POST',
|
||||
data:{type:$('#expressions').val()}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<br />
|
||||
<form action="customer" method="POST">
|
||||
Contact Info: <input type="text" name="contactInfo" /> <br />
|
||||
Contact Info Type: <select id="expressions" ></select> <br />
|
||||
<input type="submit" value="Submit" />
|
||||
</form>
|
||||
<br /><br />
|
||||
<span th:text="${message}"></span><br />
|
||||
<span id="contactInfoType" th:text="${contactInfoType}" style="visibility:hidden"></span><br />
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user