Introduction
I was strugling with the apache commons email validator. This litle baby was not working according the specs they gave me. After a while I gave up on that and descided against my own rules to build it myself. What I mean with against my own rules is: Dont build if it is out there in a proper library. But in this case I had an exception.
The best way to solve this issue was to use a regular expression. Not my favorite but mighty handy when you need them.
Solution:
The scary part:
For those who have no experience with R.E. this might look like cursing in a comic :).
"^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]+)$";
Lets analyze this:First lets have a look at the structure and later on we spill some information about the details.
The first thing you might notice in the structure are blocks like these [_A-Za-z0-9-\\+]+the A-Z, a-z or 0-9 this means that it contains an character in capitals (A-Z), or in non-capitals(a-z)or digits from 0-9. if the notation is like:[_A-Za-z0-9] It will only search for one character each.if you add a + it means iterate till you can find no more.if you add {2} or {2,5} instead of a + it means only 2 characters or from 2 to 5 characters.
In the case of the email validator you also need one .(dot) and one @ as you can see they are not followed by the annotations I described to iterate for more.
Some of the details:
^ the carrot sign before the brackets means "Starts with" So in this case It can be a multiple underscores, characters or numbers.
The ^ inside the brackets means not like [^A-Z] everything but capitals.
The * is the same as + occurs 1 or more times (iteration).
The $ checks if the end of line is following.
Conclusion:
It still looks like cursing in a comic or something that gives you an headache. But it is the way forward if you want to check a string on patterns. This whole exercise is useless without execution. So you still need to use the Pattern and Matcher class (Examples all over the internet).
Or use the String.matches method. Will do two.
Have fun!
dinsdag 24 juni 2014
maandag 9 juni 2014
scraping html with selenium server
Introduction:
In this case I tried to create a server that is capable of getting the values from an html file. The first part what is needed I describe here.
The first part is of course to get the html from the url. This part you can do with Selenium Server, this is an java library which integrates selenium into the virtual machine. This is actual not the hardest part. The hardest part I am working currently namely to get crappy html a bit xml compliant.
The example:
public class Scraper {
private static final String BROWSER = "*firefox";
private static final String SERVER = "localhost";
private static final int PORT = 4444;
private static final String SLASHES = "//";
private static final String SLASH = "/";
private DefaultSelenium selenium;
private String url;
public Scraper(String url) {
this.url = url;
}
public void startScraper() {
//This is to separate the server from the page where you want to start
int startPosition = url.indexOf(SLASHES) + SLASHES.length();
//this turns http://google.nl/search into google.nl/search
String tmpUrl = url.substring(startPosition);
int endPosition = tmpUrl.indexOf(SLASH);
//this turns http://google.nl/search into google.nl
String baseUrl = url.substring(0, endPosition + startPosition);
//this turns http://google.nl/search into /search
String pageUrl = url.substring(endPosition + startPosition, url.length());
//instanciate selenium with a port, your browser and the baseUrl
selenium = new DefaultSelenium(SERVER, PORT, BROWSER, baseUrl);
try {
//instanciate the selenium server
SeleniumServer server = new SeleniumServer();
server.start();
selenium.start();
//open the page you like search in this example
selenium.open(pageUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
//This method is the first part for xml compliancy.
//In my case the data I want is allways in the body.
public String createHTmlOutPutStream () {
String htmlSource = selenium.getHtmlSource();
int start = htmlSource.indexOf("<body");
int stop = htmlSource.indexOf("</body>") + 7 ;
htmlSource = htmlSource.substring(start,stop);
return htmlSource;
}
// This method fills every textfield if you know the name
public void populateTextField(String fieldName, String text) {
selenium.type(fieldName, text);
}
// This method clicks the button for you
public void clickButton(String buttonName) {
selenium.click(buttonName);
}
// This method runs through every option in a dropdown list.
public void chooseDropDownAll(String dropDownName) {
String[] options = selenium.getSelectOptions("dropDownName");
for (String option : options) {
selenium.select("dropDownName", option);
}
}
// This method only picks one option in the dropdown list.
public void chooseDropDownSpecific(String dropDownName, String optionName) {
selenium.select("dropDownName", optionName);
}
}
Conclusion:
With those two libraries:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>2.42.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>2.42.0</version>
you will be capable of doing this trick. This only a small set of possibilities to discover.
You should try it, the next thing what I want to do is to write a test that does the login and the first search for me on the project I am working on right now. This because I like programming and not logging in :).
Have fun!
In this case I tried to create a server that is capable of getting the values from an html file. The first part what is needed I describe here.
The first part is of course to get the html from the url. This part you can do with Selenium Server, this is an java library which integrates selenium into the virtual machine. This is actual not the hardest part. The hardest part I am working currently namely to get crappy html a bit xml compliant.
The example:
public class Scraper {
private static final String BROWSER = "*firefox";
private static final String SERVER = "localhost";
private static final int PORT = 4444;
private static final String SLASHES = "//";
private static final String SLASH = "/";
private DefaultSelenium selenium;
private String url;
public Scraper(String url) {
this.url = url;
}
public void startScraper() {
//This is to separate the server from the page where you want to start
int startPosition = url.indexOf(SLASHES) + SLASHES.length();
//this turns http://google.nl/search into google.nl/search
String tmpUrl = url.substring(startPosition);
int endPosition = tmpUrl.indexOf(SLASH);
//this turns http://google.nl/search into google.nl
String baseUrl = url.substring(0, endPosition + startPosition);
//this turns http://google.nl/search into /search
String pageUrl = url.substring(endPosition + startPosition, url.length());
//instanciate selenium with a port, your browser and the baseUrl
selenium = new DefaultSelenium(SERVER, PORT, BROWSER, baseUrl);
try {
//instanciate the selenium server
SeleniumServer server = new SeleniumServer();
server.start();
selenium.start();
//open the page you like search in this example
selenium.open(pageUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
//This method is the first part for xml compliancy.
//In my case the data I want is allways in the body.
public String createHTmlOutPutStream () {
String htmlSource = selenium.getHtmlSource();
int start = htmlSource.indexOf("<body");
int stop = htmlSource.indexOf("</body>") + 7 ;
htmlSource = htmlSource.substring(start,stop);
return htmlSource;
}
// This method fills every textfield if you know the name
public void populateTextField(String fieldName, String text) {
selenium.type(fieldName, text);
}
// This method clicks the button for you
public void clickButton(String buttonName) {
selenium.click(buttonName);
}
// This method runs through every option in a dropdown list.
public void chooseDropDownAll(String dropDownName) {
String[] options = selenium.getSelectOptions("dropDownName");
for (String option : options) {
selenium.select("dropDownName", option);
}
}
// This method only picks one option in the dropdown list.
public void chooseDropDownSpecific(String dropDownName, String optionName) {
selenium.select("dropDownName", optionName);
}
}
Conclusion:
With those two libraries:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>2.42.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>2.42.0</version>
you will be capable of doing this trick. This only a small set of possibilities to discover.
You should try it, the next thing what I want to do is to write a test that does the login and the first search for me on the project I am working on right now. This because I like programming and not logging in :).
Have fun!
zondag 4 mei 2014
Jpa another way of persisting
Introduction:
To deal with persistence in Java is getting less complicated by the tools that are being offered to us. The complication lies in the fact what to choose and what kind of strategy should you choose. In my previous blog I opened the doors to JPA which i denied to exist for a couple of years. "Just another Hibernate" was my defense. Looking at it from a historical point of view, My thoughts where based on some points. Hibernate was there together with toplnk and EJB to deal with ORM before JPA. These three tools where the bases for the reference called JPA. At last I opened that small and started being interested in JPA. I have to admit it is getting to me. I really like the way the things have been setup. A lot of people that tried to explain to me that JPA gave more freedom, have been shot by me as evangelists. The fun part of the story is, that not there preaching but a project that was using JPA brought me the light.
The example:
There are a couple of ways to deal with persistence in JPA. The most easy and fun one are repositories. I have them on my list to be study. But for now there is SQL, HQL (hibernate) and JQL (jpa). Sql gives you the straight forward way to acces an database something select * from customers or update customers set name = 'john doe' where id = 1 should look familiair. In JQL this looks pretty much the same but you are not talking to the database but to the objects that are representing the database in the application called entities.
So we have a simple Java pojo for customers with a customer name (I like it simple :)):
Lets use Lombok for fun:
public class Customer {
@Id
@GeneratedValue
@Getter
@Setter
private long id;
//lombok annotations.
@Getter
@Setter
private String name;
}
//Now we make it persistable:
@Entity
//the table to point to the name is not mandotory if the class has the same name as the database table.
@Table(name="customer")
public class Customer {
@Id
@GeneratedValue
@Getter
@Setter
private long id;
//lombok annotations.
@Getter
@Setter
@Column //you could also use the name attribute if the column name in the table difffers from the class //member name.
private String name;
}
To deal with persistence in Java is getting less complicated by the tools that are being offered to us. The complication lies in the fact what to choose and what kind of strategy should you choose. In my previous blog I opened the doors to JPA which i denied to exist for a couple of years. "Just another Hibernate" was my defense. Looking at it from a historical point of view, My thoughts where based on some points. Hibernate was there together with toplnk and EJB to deal with ORM before JPA. These three tools where the bases for the reference called JPA. At last I opened that small and started being interested in JPA. I have to admit it is getting to me. I really like the way the things have been setup. A lot of people that tried to explain to me that JPA gave more freedom, have been shot by me as evangelists. The fun part of the story is, that not there preaching but a project that was using JPA brought me the light.
The example:
There are a couple of ways to deal with persistence in JPA. The most easy and fun one are repositories. I have them on my list to be study. But for now there is SQL, HQL (hibernate) and JQL (jpa). Sql gives you the straight forward way to acces an database something select * from customers or update customers set name = 'john doe' where id = 1 should look familiair. In JQL this looks pretty much the same but you are not talking to the database but to the objects that are representing the database in the application called entities.
So we have a simple Java pojo for customers with a customer name (I like it simple :)):
Lets use Lombok for fun:
public class Customer {
@Id
@GeneratedValue
@Getter
@Setter
private long id;
//lombok annotations.
@Getter
@Setter
private String name;
}
//Now we make it persistable:
@Entity
//the table to point to the name is not mandotory if the class has the same name as the database table.
@Table(name="customer")
public class Customer {
@Id
@GeneratedValue
@Getter
@Setter
private long id;
//lombok annotations.
@Getter
@Setter
@Column //you could also use the name attribute if the column name in the table difffers from the class //member name.
private String name;
}
if JPA is configured correctly this class is coupled to the table now by the ORM of JPA.
But now my customers are hooked up with the products they bought from me That is going to give me an N to N relation ship. 1 customer can buy multiple products and 1 product could been bought by multiple customers. An N to N relation ship can only achieved through a coupling table in the database. It would be really annoying if the represenation of your class model should be one on one with the database. This means that you would need to model all your coupling tables which yo are not going to need to present your data.
One of the things we can do is Model it with @named queries in JPA That would look something like this:
@Entity
//the table to point to the name is not mandotory if the class has the same name as the database table.
@Table(name="customer")
//The JPA named query
@NamedQuery(name = "selectPrdFromCustomer" , query = "select c.products from Customers c where c.id = ?1 ") })
public class Customer {
private long id;
//lombok annotations.
@Getter
@Setter
@Column //you could also use the name attribute if the column name in the table difffers from the class //member name.
private String name;
//lombok annotations.
@Getter
@Setter
}
//the table to point to the name is not mandotory if the class has the same name as the database table.
@Table(name="customer")
//The JPA named query
@NamedQuery(name = "selectPrdFromCustomer" , query = "select c.products from Customers c where c.id = ?1 ") })
public class Customer {
private long id;
//lombok annotations.
@Getter
@Setter
@Column //you could also use the name attribute if the column name in the table difffers from the class //member name.
private String name;
//lombok annotations.
@Getter
@Setter
//ManyToMany is the equilevant for N to N cascading all means get all the data you can on all the levels allowed.
@ManyToMany(cascade = CascadeType.ALL)
//The CUSTOMER_PRODUCT table is the coupling table. The join collumn is the collumn where the id from this class should couple with. the inverseJoinColum is the id of the products where it should couple to.
@JoinTable(name = "CUSTOMER_PRODUCT", joinColumns = @JoinColumn(name = "product_id"), inverseJoinColumns = @JoinColumn(name = "id"))
Private List<Products> products
}
At this point you can that a normal sql query has been handled on Entity level. The interesting part is that this sql query is separated on two different places. The named query is taking responsibility for the selecting part while the ManyToMany and the JoinTable is taking the responsibility for the coupling part.
As last you can create an PersistenceController or manager and that would need to do something like this:
Public PersistenceController {
@PersistenceContext
private EntityManager em;
@Setter
@Getter
private long customerId;
public List<String getProductNames() {
public List<String> product name = em.createNamedQuery("selectPrdFromCustomer").setParameter(1, customerId).getSingleResult();
//The getSingleResult is only applicable if you really want to have one result instead of an list but then the type of the method should be also String and not al list.
}
}
Conclusion:
Ones you know how to deal with persistence like this it is easy. But to learn it can give you a bad hadache. It is worth the effort That is for sure. Just try the example that has been given and have FUN!
zaterdag 26 april 2014
peristence future arrived
Traditionally Java and databases have been on friends. Starting with the java persistence libraries where soon enough we could use prepared statements to secure the way we queried the database. After that the world of Java was shocked with the birth of ORM toolings. These babies really decoupled the whole data tier from the rest and saved a lot of work. Implementations of JPA and Eclipse (Top) link helped the word easy up the way of persistence. That the future is allways one step away is common knowledge these days. But in some cases the future allready catched up with me before I realize this. m
In the case of JPA repositories that happened. I figured this technique out the last couple of weeks and I am already in love with it. They pushed things a little bit further then my imagination would go. It is not Star trek yet but still quite impressive.
The concept:
The Idea behind this to diminish the boiler plate coding further. The benefits of this I can bring down to two points:
- After configuring this right which is a bit more work, the coding comes down to allmost nothing.
- Because of the fact that the persistence part is mostly configuration, the repositories them selves can (not necessarily) function as a complete database tier.
The configuration:
The configuration I set up is a mix of spring and maven:
Maven pom part:
<properties>
<spring.version>4.0.3.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp</artifactId>
<version>0.8.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.5.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.4.Final</version>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.0-801.jdbc4</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.5.Final</version>
//could not load the JPA from here so I did it separate.
<exclusions>
<exclusion>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
</exclusion>
</exclusions>
</dependency>
//The jpa libary that is needed for hibernate.
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency>
the persistence xml which needs to be placed in src/main/resources/META-INF.
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="dataSource" transaction-type="RESOURCE_LOCAL">
<description><YOUR DESCRIPTION></description>
<class>com.shops.data.info.CustomerInfo</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/shops" />
<property name="javax.persistence.jdbc.user" value="<USERNAME>" />
<property name="javax.persistence.jdbc.password" value="<PASSWORD>" />
//optional parameters.
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
</persistence>
The spring context file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<jpa:repositories base-package="THE REPOSITORY PACKAGE"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/<YOURDATABASE>"/>
<property name="username" value="<USERNAME>"/>
<property name="password" value="PASSWORD"/>
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="database" value="POSTGRESQL"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<!-- spring based scanning for entity classes-->
<property name="packagesToScan" value="<THE D.O. PACKAGE>"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"/>
</beans>
The repository part:
You can have multiple repositories. How to deal with the number of repositories depends completely on the fact how you want to deal delete with your data.
Here is al single example:
import com.my.web.shop.dataobjects.CustomerInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
import java.util.List;
@Repository
@Transactional
interface CustomerRepository extends JpaRepository<CustomerInfo, Long > {
public List<CustomerInfo> findByEmailadressAndPassword(String email, String password);
public List<CustomerInfo> findByEmailadress(String email);
}
In this litle piece of code you find some astonishing things first of all after creating this interface, I did not create an implementation. Creating your own repository is not necessary in the most cases. As a matter of fact if you create an Repository on your own, you be at the point where we would start writing this extra boiler plate code we done for years.
Under water this interface is hooked up with the CrudRepository of Spring. This baby gives you allmost everything you need. All the basic database actions as select, update, delete and insert are there.
The second part you might find different is the naming of the methods. This is actually one of the most amazing parts. In the name of the method you declare the fields which you want to use in your sql statement. The parameters represent the values. So the first method would build under water: where emailAdress = "a@b.nl" and password = "myPassword.". If you have a big query the name of your method would become very long. Luckily there is another way to deal with queries. The @Query annotation helps to solve this problem. It could look something like this:
//The D.O. for the myShop customers.
@Entity
@Table(name = "customers")
public class CustomerInfo implements Serializable{
@Id
@GeneratedValue
private long id;
@Column
private String emailadress;
@Column
private String password;
@Id
public Long getId() {
return id;
}
public String getPassword() {
return password;
}
public void setId(Long id) {
this.id = id;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmailadress() {
return emailadress;
}
public void setEmailadress(String emailadress) {
this.emailadress = emailadress;
}
}
// The D.O that couples that couples the customer to the test data. And contains the test data.
@Entity
@Table(name = "test")
public class Test implements Serializable {
@Id
@GeneratedValue
private long id;
@Column
private String label;
@Column(name = "customer_id")
private long customersId;
@OneToMany()
@JoinColumn(name="id")
private List<CustomerInfo> customerInfo;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public long getCustomersId() {
return customersId;
}
public void setCustomersId(long customersId) {
this.customersId = customersId;
}
}
//The test data repository
import com.shops.data.info.Test;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
import java.util.List;
/**
* Created by compurat on 4/19/14.
*/
@Repository
@Transactional
interface TestRepository extends JpaRepository<Test, Long > {
@Query("SELECT t.label FROM Test t left join t.customerInfo c where t.id=(?1)")
public String findById(long id);
}
As you can see the findById method is not acting on the method name and the parameter value but will act on the @Query that we put on top of it. The last part of the query works in a simular way as we know with PreparedStatement. The questionmark tells the compiler this a placeholder an d the number tells which parameter in line it needs to pickup. In this case we only have one parameter. Not enough space for a mistake :).
There is another piece that might have caught your eye. There is a join in this query. It took me a while to figure out how that worked. The secret lies in the simple fact that you have to divide the join over two places.
- @OneToMany()@JoinColumn(name="id")private List<CustomerInfo> customerInfo; defines this part of the join. It tells: listen there is a join coming up. In this case it is a OneToMany but it can also be @ManyToMany or @OneToOne. The @JoinColumn tells to connect to a certainfield in the CustomerInfo class.
- The left join t.customerInfo c in the @Query part tells to actually execute the join. As you might notice the ON part from sql is not translated here. That is one of the parts That still puzzles me.How is it known to couple to? For the rest As allways as you understand the concept You find out it was not as hard as you expected first.
Conclusion:
The concept itself and the amazement it gave me leveled up the steepness for me to understand it. But now I am happy I gave it time and picked up the things I allready know now. The concept to me is still a bit futuristic. But the fact it is here and I love to use it. The power of this is amazing.
Have fun!
dinsdag 25 maart 2014
Test with Wicket and Spring
Introduction:
I started working with Wicket and as a Java developer I like the concept. I think when there are really front end developers working, it is harder to defend the fact that you want to use wicket. Wicket brings it own html notations. Most frontenders are not keen on that. For working with Wicket there is a very good starting point: the wicket free guide. The interesting part starts when you are about to use DI and Wicket. Setting that up is not to hard The web.xml should look like this:
<web-app>
<display-name>MyApp</display-name>
<filter>
<filter-name>MyAppFilter</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>com.my.app.MyApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MyAppFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
For maven just get the latest version of wicket and spring and you be up and running in no time.
The problem:
The thing i ran into was the part where I wanted to start testing with Wicket using some DI to deal with some Classes which otherwise would end up in a very complex design. So the thing I cooked up after reading a lot of examples on the internet that didn't work.
The spring test config in src/test/resources:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean id="classa" class="com.myapp.ClassA">
</bean>
<bean id="classb" class="com.myapp.ClassB">
</bean>
<bean id="wicketApplication" class="com.myapp.MyWicketApp">
</bean>
</beans>
The Junit test:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:myApp-test-context.xml" })
public class LoginTest {
The mock Application:
public class MyAppStub extends AmyApp {
private final ApplicationContextMock applicationContextMock = new ApplicationContextMock();
//injecting the classes from the test context.
@Inject
private ClassA classa;
@Inject
private ClassB classb;
protected ApplicationContextMock getApplicationContextMock() {
return applicationContextMock;
}
@Override
public Class<? extends Page> getHomePage() {
// TODO Auto-generated method stub
return null;
}
@Override
public void init() {
//Adding the injected classes to the context mock so they will be used during testing.
applicationContextMock.putBean("classa",
classa);
applicationContextMock.putBean("classb",
classb);
//adding the applicationmock to spring
getComponentInstantiationListeners().add(
new SpringComponentInjector(this, applicationContextMock));
}
}
Conclusion:
After I figured out how this baby works it is not that hard anymore to test with wicket. All you have to do is figure out the right pieces of the puzzle. In all the other examples the same pieces where missing.
I hope This helps.
Have Fun!
I started working with Wicket and as a Java developer I like the concept. I think when there are really front end developers working, it is harder to defend the fact that you want to use wicket. Wicket brings it own html notations. Most frontenders are not keen on that. For working with Wicket there is a very good starting point: the wicket free guide. The interesting part starts when you are about to use DI and Wicket. Setting that up is not to hard The web.xml should look like this:
<web-app>
<display-name>MyApp</display-name>
<filter>
<filter-name>MyAppFilter</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>com.my.app.MyApp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MyAppFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
For maven just get the latest version of wicket and spring and you be up and running in no time.
The problem:
The thing i ran into was the part where I wanted to start testing with Wicket using some DI to deal with some Classes which otherwise would end up in a very complex design. So the thing I cooked up after reading a lot of examples on the internet that didn't work.
The spring test config in src/test/resources:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean id="classa" class="com.myapp.ClassA">
</bean>
<bean id="classb" class="com.myapp.ClassB">
</bean>
<bean id="wicketApplication" class="com.myapp.MyWicketApp">
</bean>
</beans>
The Junit test:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:myApp-test-context.xml" })
public class LoginTest {
private WicketTester wicketTester;
@Inject
// this stub is inheriting from an abstract class which is enhiriting from the wicket
WebApplication otherwise I cannot DI with the same type. The real app is also inheriting from
that abstract class
private AmyApp myAppStub;
@Before
public void init() {
wicketTester = new WicketTester(myAppStub);
}
}
The mock Application:
public class MyAppStub extends AmyApp {
private final ApplicationContextMock applicationContextMock = new ApplicationContextMock();
//injecting the classes from the test context.
@Inject
private ClassA classa;
@Inject
private ClassB classb;
protected ApplicationContextMock getApplicationContextMock() {
return applicationContextMock;
}
@Override
public Class<? extends Page> getHomePage() {
// TODO Auto-generated method stub
return null;
}
@Override
public void init() {
//Adding the injected classes to the context mock so they will be used during testing.
applicationContextMock.putBean("classa",
classa);
applicationContextMock.putBean("classb",
classb);
//adding the applicationmock to spring
getComponentInstantiationListeners().add(
new SpringComponentInjector(this, applicationContextMock));
}
}
Conclusion:
After I figured out how this baby works it is not that hard anymore to test with wicket. All you have to do is figure out the right pieces of the puzzle. In all the other examples the same pieces where missing.
I hope This helps.
Have Fun!
dinsdag 18 maart 2014
CDI (context dependency injection JSR 299) and Junit Testing.
Introduction:
DI is unthinkable these days. Having different variations on the same concept in different classes and of course a separate context for testing. Although for testing mocking instead of stubbing is also a very valid option. I have been playing around with Spring and with Google guice but I never came around to play with CDI. I have been playing with it today And I must say it is quiet charming. I really loved the simple and direct way of annotating stuff and no traces of xml files (only if you want too).
The part I want to describe is the part to use for testing. It reminds me a lot of how that works with spring apart from the fact that I did not had to point to a context.xml file.
The example:
Because the jsr 299 is a reference, the main parties allready have build there implementation for it :
(The versions are at this point in time (march 2014) the latest.
DI is unthinkable these days. Having different variations on the same concept in different classes and of course a separate context for testing. Although for testing mocking instead of stubbing is also a very valid option. I have been playing around with Spring and with Google guice but I never came around to play with CDI. I have been playing with it today And I must say it is quiet charming. I really loved the simple and direct way of annotating stuff and no traces of xml files (only if you want too).
The part I want to describe is the part to use for testing. It reminds me a lot of how that works with spring apart from the fact that I did not had to point to a context.xml file.
The example:
Because the jsr 299 is a reference, the main parties allready have build there implementation for it :
(The versions are at this point in time (march 2014) the latest.
- JBoss it would be:
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-core</artifactId>
<version>2.2.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
- Apache
<dependency>
<groupId>org.apache.openwebbeans</groupId>
<artifactId>openwebbeans-impl</artifactId>
<version>1.2.2</version>
</dependency>
To write a piece of code that chooses the depedency for its needs CDI is great in being simple:
The interface that makes the difference:
public interface IHelloWorld {
void sayHello();
}
The class that does my realtime serious business kind of logic:
import javax.enterprise.inject.Alternative;
//This annotation tells the CDI container that it is one of the many implementations.
@Alternative
public class HelloWorld implements IHelloWorld {
public void sayHello() {
System.out.println("Hello world");
}
}
The class that does my very serious alternative kind of business logic or test stubbing.
import javax.enterprise.inject.Alternative;
//This annotation tells the CDI container that it is one of the many implementations.
@Alternative
public class HelloAlternative implements IHelloWorld {
public void sayHello() {
System.out.println("hello alternative world");
}
The class that is complete unaware of the fact that he does not speak to the same injected all the time. Love to keep this one in the dark about that.
import javax.inject.Inject;
public class LoginBean {
//This is the actual injection of the desired class.
@Inject
private IHelloWorld helloWorld;
public void print() {
helloWorld.sayHello();
}
}
The first test that uses my very serious business logic saying: "Hello world "
import javax.inject.Inject;
import org.jglue.cdiunit.ActivatedAlternatives;
import org.jglue.cdiunit.CdiRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
//The annotation that hooks this test up with te CDI container
@RunWith(CdiRunner.class)
// The annotation that tells which implementation of the IHelloWorld Interf to use.
@ActivatedAlternatives(HelloWorld.class)
public class HelloWorldTest {
//Injects the bean that has a DI itself.
@Inject
LoginBean loginBean;
@Test
public void test() {
loginBean.print();
//outcome : "Hello world"
}
import javax.inject.Inject;
import org.jglue.cdiunit.ActivatedAlternatives;
import org.jglue.cdiunit.CdiRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
//The annotation that hooks this test up with te CDI container
@RunWith(CdiRunner.class)
// The annotation that tells which implementation of the IHelloWorld Interf to use.
@ActivatedAlternatives(HelloWorld.class)
public class HelloAlternativeTest {
@Inject
LoginBean loginBean;
@Test
public void test() {
loginBean.print();
//outcome: hello alternative world
}
At last but not least the full Apache maven tech stack:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.jglue.cdi-unit</groupId>
<artifactId>cdi-unit</artifactId>
<version>2.1.0</version>
<scope></scope>
</dependency>
And the full JBoss maven tech stack:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
</dependency>
<dependency>
<groupId>org.jglue.cdi-unit</groupId>
<artifactId>cdi-unit</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-core</artifactId>
<version>2.2.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
Conclusion:
If you are using the Apache stack and you want to move to the JBoss stack or visa versa, that does not mather. They bot comply to the JSR 299. There is no need for code changing. To me personal this way of DI is more intuitive and very powerfull by the annotatons it is using. Give it a try and let me know what you think of it.
Have fun!
dinsdag 11 maart 2014
Find position and insert characters
Introduction:
I was working on formatting wrongly entered numberplates of a car. One business rule was to format all of them in the right perspective. Like 11aa33 should be 11-AA-33. But how to find out where to put the minusses.
The solution
First of all make sure you only have capitals like:
numberplate.toUpperCase();
This takes care of all the characters in the numberplate.
The second step is:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
private static final String MINUS = "-";
private static final String DIGIT_MATCH = "[0-9]{1,3}";
private static final String CHARACTER_MATCH = "[A-Z]{1,3}";
private static final String DIGIT_MATCH = "[0-9]{1,3}";
private static final String CHARACTER_MATCH = "[A-Z]{1,3}";
String formatted = kenteken;
//counting the right amount of minusses.
//counting the right amount of minusses.
if (StringUtils.countMatches(kenteken, MINUS) != 2) {
//the actual patterns to find
Pattern digitPattern = Pattern.compile(DIGIT_MATCH);
Pattern charsPattern = Pattern.compile(CHARACTER_MATCH);
Pattern digitPattern = Pattern.compile(DIGIT_MATCH);
Pattern charsPattern = Pattern.compile(CHARACTER_MATCH);
// find the matches
Matcher digitMatcher = digitPattern.matcher(formatted);
Matcher charsMatcher = charsPattern.matcher(formatted);
Matcher digitMatcher = digitPattern.matcher(formatted);
Matcher charsMatcher = charsPattern.matcher(formatted);
// adding the minusses
if (digitMatcher.find()) {
formatted = new StringBuffer(formatted).insert(
digitMatcher.end(), MINUS).toString();
}
if (charsMatcher.find()) {
formatted = new StringBuffer(formatted).insert(
charsMatcher.end(), MINUS).toString();
}
}
return formatted;
Have fun!
formatted = new StringBuffer(formatted).insert(
digitMatcher.end(), MINUS).toString();
}
if (charsMatcher.find()) {
formatted = new StringBuffer(formatted).insert(
charsMatcher.end(), MINUS).toString();
}
}
return formatted;
Have fun!
Abonneren op:
Posts (Atom)