diff --git a/jee7/pom.xml b/jee7/pom.xml index addb586b74..e398651055 100644 --- a/jee7/pom.xml +++ b/jee7/pom.xml @@ -98,7 +98,16 @@ shrinkwrap-resolver-impl-maven-archive test - + + org.apache.httpcomponents + httpclient + 4.5 + + + commons-io + commons-io + 2.4 + com.sun.faces jsf-api @@ -378,5 +387,21 @@ + + webdriver-chrome + + true + + + chrome + + + + + webdriver-firefox + + firefox + + diff --git a/jee7/src/main/webapp/ConvListVal.xhtml b/jee7/src/main/webapp/ConvListVal.xhtml index e5425e87a5..8c5213764c 100644 --- a/jee7/src/main/webapp/ConvListVal.xhtml +++ b/jee7/src/main/webapp/ConvListVal.xhtml @@ -8,7 +8,7 @@

Testing converters

- + @@ -19,13 +19,13 @@ - +
- + - +
@@ -41,7 +41,7 @@ - +
diff --git a/jee7/src/main/webapp/WEB-INF/faces-config.xml b/jee7/src/main/webapp/WEB-INF/faces-config.xml new file mode 100644 index 0000000000..d5b2cd6612 --- /dev/null +++ b/jee7/src/main/webapp/WEB-INF/faces-config.xml @@ -0,0 +1,13 @@ + + + + convListVal + com.baeldung.convListVal.ConvListVal + session + + \ No newline at end of file diff --git a/jee7/src/main/webapp/WEB-INF/web.xml b/jee7/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..11bd87cf99 --- /dev/null +++ b/jee7/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,41 @@ + + + + + Faces Servlet + javax.faces.webapp.FacesServlet + + + Faces Servlet + *.jsf + + + javax.faces.PROJECT_STAGE + Development + + + State saving method: 'client' or 'server' (default). See JSF Specification section 2.5.2 + javax.faces.STATE_SAVING_METHOD + client + + + + index.jsf + welcome.jsf + index.html + index.jsp + + \ No newline at end of file diff --git a/jee7/src/test/java/com/baeldung/convListVal/ConvListValTest.java b/jee7/src/test/java/com/baeldung/convListVal/ConvListValTest.java new file mode 100644 index 0000000000..4450a26f43 --- /dev/null +++ b/jee7/src/test/java/com/baeldung/convListVal/ConvListValTest.java @@ -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); + } + +} diff --git a/libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java b/libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java index 3190debef8..a5613e2406 100644 --- a/libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java @@ -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 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)); } diff --git a/mybatis/pom.xml b/mybatis/pom.xml new file mode 100644 index 0000000000..56de727b21 --- /dev/null +++ b/mybatis/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + com.baeldung + mybatis + 1.0.0-SNAPSHOT + + 4.12 + 10.13.1.1 + 3.2.2 + + + + org.apache.derby + derby + ${derby.version} + + + org.mybatis + mybatis + ${mybatis.version} + + + junit + junit + ${junit.version} + test + + + + \ No newline at end of file diff --git a/mybatis/src/main/java/com/baeldung/mybatis/mapper/AddressMapper.java b/mybatis/src/main/java/com/baeldung/mybatis/mapper/AddressMapper.java new file mode 100644 index 0000000000..588707383b --- /dev/null +++ b/mybatis/src/main/java/com/baeldung/mybatis/mapper/AddressMapper.java @@ -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); +} diff --git a/mybatis/src/main/java/com/baeldung/mybatis/mapper/PersonMapper.java b/mybatis/src/main/java/com/baeldung/mybatis/mapper/PersonMapper.java new file mode 100644 index 0000000000..ab207325ad --- /dev/null +++ b/mybatis/src/main/java/com/baeldung/mybatis/mapper/PersonMapper.java @@ -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 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); + +} diff --git a/mybatis/src/main/java/com/baeldung/mybatis/model/Address.java b/mybatis/src/main/java/com/baeldung/mybatis/model/Address.java new file mode 100644 index 0000000000..f32e47aef2 --- /dev/null +++ b/mybatis/src/main/java/com/baeldung/mybatis/model/Address.java @@ -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; + } + +} diff --git a/mybatis/src/main/java/com/baeldung/mybatis/model/Person.java b/mybatis/src/main/java/com/baeldung/mybatis/model/Person.java new file mode 100644 index 0000000000..248e3ca7a1 --- /dev/null +++ b/mybatis/src/main/java/com/baeldung/mybatis/model/Person.java @@ -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
addresses; + + public Person() { + } + + public Person(Integer personId, String name) { + this.personId=personId; + this.name = name; + addresses = new ArrayList
(); + } + + 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
getAddresses() { + return addresses; + } +} diff --git a/mybatis/src/main/java/com/baeldung/mybatis/utils/MyBatisUtil.java b/mybatis/src/main/java/com/baeldung/mybatis/utils/MyBatisUtil.java new file mode 100644 index 0000000000..a045e70333 --- /dev/null +++ b/mybatis/src/main/java/com/baeldung/mybatis/utils/MyBatisUtil.java @@ -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(); + } +} diff --git a/mybatis/src/main/resources/mybatis-config.xml b/mybatis/src/main/resources/mybatis-config.xml new file mode 100644 index 0000000000..6987797068 --- /dev/null +++ b/mybatis/src/main/resources/mybatis-config.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mybatis/src/test/java/com/baeldung/mybatis/mapper/PersonMapperTest.java b/mybatis/src/test/java/com/baeldung/mybatis/mapper/PersonMapperTest.java new file mode 100644 index 0000000000..8724aaa545 --- /dev/null +++ b/mybatis/src/test/java/com/baeldung/mybatis/mapper/PersonMapperTest.java @@ -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 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(); + + } + +} diff --git a/pom.xml b/pom.xml index 1a11bd055f..a705ac7cb1 100644 --- a/pom.xml +++ b/pom.xml @@ -215,6 +215,7 @@ vertx spring-data-gemfire cucumber + mybatis diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java new file mode 100644 index 0000000000..41f873b42a --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfo.java @@ -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[] payload() default {}; + +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java new file mode 100644 index 0000000000..a8393e2739 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/ContactInfoValidator.java @@ -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 { + + @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; + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java new file mode 100644 index 0000000000..361a7b1c03 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/DynamicValidationApp.java @@ -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); + } +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java new file mode 100644 index 0000000000..44db2d5228 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/CustomerController.java @@ -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 getContactInfoType(Model model) { + return expressionRepository.findAll(); + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java new file mode 100644 index 0000000000..0eeac2a8dc --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/config/PersistenceConfig.java @@ -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; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java new file mode 100644 index 0000000000..ccacc297a5 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/dao/ContactInfoExpressionRepository.java @@ -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 { + +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java new file mode 100644 index 0000000000..9c202b07c8 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/ContactInfoExpression.java @@ -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; + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java new file mode 100644 index 0000000000..f043458fce --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/dynamicvalidation/model/Customer.java @@ -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; + } + +} diff --git a/spring-boot/src/main/resources/data-expressions.sql b/spring-boot/src/main/resources/data-expressions.sql new file mode 100644 index 0000000000..3e702a759d --- /dev/null +++ b/spring-boot/src/main/resources/data-expressions.sql @@ -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})?(\/.*)?$') \ No newline at end of file diff --git a/spring-boot/src/main/resources/schema-expressions.sql b/spring-boot/src/main/resources/schema-expressions.sql new file mode 100644 index 0000000000..59f6ab05eb --- /dev/null +++ b/spring-boot/src/main/resources/schema-expressions.sql @@ -0,0 +1,5 @@ +create table contact_info_expression( + expression_type varchar(50) not null, + pattern varchar(500) not null, + PRIMARY KEY ( expression_type ) +); \ No newline at end of file diff --git a/spring-boot/src/main/resources/templates/customer.html b/spring-boot/src/main/resources/templates/customer.html new file mode 100644 index 0000000000..6aec5ab590 --- /dev/null +++ b/spring-boot/src/main/resources/templates/customer.html @@ -0,0 +1,41 @@ + + + +Customer Page + + + + +
+
+Contact Info:
+Contact Info Type:
+ +
+

+
+
+ + \ No newline at end of file