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;

}

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
//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


Introduction:

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:


  1. After configuring this right which is a bit more work, the coding comes down to allmost nothing.
  2. 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 is a combination between JPA and spring in my example. There might be other implementations out there where I don't have knowledge of.

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. 

  1.     @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. 
  2. 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 {
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.

  • 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 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}";

        String formatted = kenteken;
//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);
          // find the matches
            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!

zondag 9 maart 2014

the power of javaassist

Introduction:

Just for fun I tried to weave a method into a class. I have been googling around to find the answers I needed to work wit javaassist. There where a lot of examples that drilled down to the same point and where not working. So i tried a bit and combined some of the stuff together.

The setting:

package org.injector.binding;

import org.injector.annotations.ComponentScan;

This pore litle guy has to say a lot but has no acces to the outside world.

public class CreateSetterStub {
private String greetingsGrashopper;

}

Luckely he has a good friend we are going to meet soon. Here we are going to call him:

public void test() {
                 // The one that needs help
Class class1 = CreateSetterStub.class;
               // Reaching out the helper.
CreateMemberSetter createMemberSetter = new CreateMemberSetter();
createMemberSetter.createSetter("greetingsGrashopper", class1.getName());
try {
CreateSetterStub createSetterStub = (CreateSetterStub)class1.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

       // The friend that is going to help
Class createSetter(String memberName,  String className) {

//The standard classpool as ued by javaassist
                ClassPool pool = ClassPool.getDefault();
// The stanndard classtype as used by javaassist
                CtClass cc = null;
//Here we teached the poor litle creature to speak.
                Class clazz = null;
try {
       Typing the speachless into the javaassist type.
               cc = pool.get(className);
         //pruning itself is a good thing: To reduce memory consumption, pruning discards                                           unnecessary attributes. But if you dont stop, you get errormessages about it. Your flow
             stops.
             cc.stopPruning(true);
             //Creating a method to speak to the outside world.
            CtMethod m2 = CtNewMethod.make("public String getText(){return \"hello world\"" + ";"
               + "}" , cc);
              //adding the method to the class. 
            cc.addMethod(m2);
           create a copy of the original class otherwise you get errors about the same class on the
              claspath.
              cc.replaceClassName(className, className + 2);
              //Type it back to the normal Java Pojo kind a type.
           clazz = cc.toClass();
              // print out the desired message. 
System.out.println( clazz.getDeclaredMethod("getText", null).invoke(clazz.newInstance(),null));
              //Still a load of exception handling todo :).
} catch (NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CannotCompileException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}  catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return clazz;

Conclusion:

Dealing with javaassist is actually amazingly simple. It has a lot of power. In that perspective, it is wise to use it when needed not for convinience. As allways with power comes responsibility :).

Have fun. 

dinsdag 3 december 2013

Time for joda time

Introduction:


Calculating time in Java is doable but it is a bit of a pain in the backside. Using the calendar, getting the days and the hours and the minutes and calculate them one by one. I been playing around with joda time and that is a relieve. They encapsulated all the complex calcuations and retrieving in methods which can be chained when necesarry.

The example:

In this example I calculate the delivery date and time of a shop. It is calculating one of those days the shop has customized times. Like normally they start at 9 in the morning but this day they start at 8.

String opening = null;
opening = "8";
String[] defaultOpenTime = defaultTime.getDefaultOpeningTime().split(":");
int defaultOpenHour = Integer.parseInt(defaultOpenTime[0]);
int customizedOpenHour = Integer.parseInt(opening);
DateTime customTime = DateTime.parse("01-12-2013");
customTime =
                customTime.hourOfDay()
                .setCopy(customizedOpenHour)
                 .minuteOfHour()
                 .setCopy(opening);
 DateTime defaultTime =
                 DateTime.now()
                 .hourOfDay()
                 .setCopy(defaultOpenHour)
                  .minuteOfHour()
                  .setCopy(defaultOpenTime[1])
                  .secondOfMinute()
                  .setCopy(00);
Hours diffHours = Hours.hoursBetween(defaultTime,customTime);
delivery = delivery.plusHours(diffHours.getHours()  + MAX_DELIVER_TIME);
if(Integer.parseInt(opening) < delivery.getHourOfDay()){
//Normally I would retreive a value from a data store and add that here instead of the          
                          opening hours.
//In this case you can only help one customer after closing hours.
delivery = delivery.hourOfDay().setCopy(opening).minuteOfHour().setCopy(opening);
delivery = delivery.plusDays(NEXT_DAY);
}

There some points I like to highlight:

In this peace of code you create a DateTime object with the date and time you desire.
customTime =
                customTime.hourOfDay()
                .setCopy(customizedOpenHour)
                 .minuteOfHour()
                 .setCopy(opening);

In this peace of code you calculate hour difference:

Hours diffHours = Hours.hoursBetween(defaultTime,customTime);

You can do this also with days, minutes and seconds.

In this piece of code you jump to the next day:

delivery = delivery.plusDays(NEXT_DAY);

You can do this also with Hours, minutes and seconds.


Conclusion

Dealing with time is much easier when you do this with the joda-time library. There is also a Joda-money library I like to play with that the next time.


Have fun!