2007-05-29

SimpleTapestry 5 CRUD application - Step XY - BeanEditForm and Grid

I've modified UserAuthenticator (added a method for getting users list,

public
List getTUsersList();


and it's implementation into
UserAuthenticatorImpl

@SuppressWarnings("unchecked") //to avoid IDE's complaints)
public List getTUsersList() {

Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
List result = session.createQuery("from TUser").list();
session.getTransaction().commit();
return result;
}

)

added 2 new pages,

Registration (BeanEditForm example, ScreenCast #4)
the page duplicates in fact AddNew page functionality, was added just as an example of different approaches
Registration.html (submitLabel="Create" is not the same as in the screencast )and Registration.java

and

Home (Grid example, ScreenCast #5). The page purpose is a) to show an example of Grid component usage; b) The grid on the page must display all the registered users (that's why
getTUsersList() was added).

Home.html
I used
<t:parameter name="passwordCell">
*****
</t:parameter>

to hide
"password" column values (see next post for other way).

public class Home { @Inject private UserAuthenticator _authenticatior;
public List getUsersList()
{
return _authenticatior.getTUsersList(); }
}


Now, after successful login navigation goes to the Home (which displays existing users list):


There are still a lot of question and things-to-be-improved... .
7. SimpleTapestry 5 CRUD application -Step 07, Cancel button, variant 1.
6. SimpleTapestry 5 CRUD application -Step 06, tweaking a grid a bit.
5. Simple Tapestry 5 CRUD application - BeanEditForm and Grid screencasts aprobation.
4. SimpleTapestry 5 CRUD application -Step 04 Adding some basic Hibernate features into the project.
3. SimpleTapestry 5 CRUD application -Step 03, "user" bean creation.
2. SimpleTapestry 5 CRUD application -Step 02, adding a service.
1. SimpleTapestry 5 CRUD application -Step 01.



2007-05-24

SimpleTapestry 5 CRUD application -Step 04 Adding some basic Hibernate features into the project.

1.Create new class package = org.example.TSA504.hibernate, name=HibernateUtil
2. Add the hibernate3.jar (I used Hibernate Core 3.2.4.SP1 ) into the project's
Java Build Path.
3. I used Hibernate on-line documentation for constructing the class
and several samples from «unknown java developers», so contact me if you think I violate someone's copyright.
4. Now, I'm using PostgreSQL 8.2 and Hibernate annotations in order to «auto-create» DB table(s), so the
hiberbate.cfg.xml file might looks like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="show_sql">true</property>
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">jdbc:postgresql://localhost/TSA</property>
<property name="connection.username">postgre</property>
<property name="connection.password">postgre</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">10</property>
<property name="jdbc.use_streams_for_binary">true</property>
<property name="transaction.flush_before_completion">true</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<mapping class="org.example.TSA504.beans.TUser"/>
</session-factory>
</hibernate-configuration>


I also have TSA DB already created (with zero tables at the moment, it means that I simly had created new DB and nothing more ) and I have postgre user among DB's Login Roles.

Note, the line

<property name="hbm2ddl.auto">create</property>

provides DB tables "auto-creation" (be means of Hibernate annotations). If you leave the line then every time you use a page linked to a table that table will be created again (and all previous data will gone away).
So, when all tables which you need were created - just comment the line.


(Another approach is to use (as it was pointed out by experienced Java-devs)
<property name="hibernate.hbm2ddl.auto">update</property>
but I haven't tried that yet)

5.Place hiberbate.cfg.xml in TSA504\src\main\resources\.
6.Add postgresql-8.1-409.jdbc3.jar library to the project.
7.
Let's tweak UserAuthenticator interface , add two new methods:

public
TUser getTUserByUserName(String userName);
public boolean addNewTUser(TUser tUser);

8.
We need to have just added methods implementation and to have isValid() method modified, so I suggest to have following UserAuthenticatorImpl.java (if you have a better implementation – I'd like to be taught ).
9. Except getting a «user» from DB, it's quite good to have ability to add new entries into DB. Try this – create new html file \TSA504\src\main\webapp\WEB-INF\AddNew.html and new page class org.example.TSA504.pages.AddNew.java (very similar to Login.java) . Also, modify our Start.html, add

<br/>
[<a t:type="PageLink" page="AddNew">Add New </a>]

10. Well, let's try to use all that - run the jetty and open http://localhost:8080/TSA504/start, click the AddNew link, fill in the form, submit and ... I got:

java.lang.ExceptionInInitializerError exception java.lang.NoClassDefFoundError: org/dom4j/DocumentException

There are, probably, no «expected» libraries ... so, I added all (just in case...) from hibernate-3.2\lib\ and
hibernate-annotations-3.3.0.GA\lib\hibernate-commons-annotations.jar into the project class-path.

Please remember also about ejb3-persistence.jar (if you'd like to use Hibernate annotations), see the previous post.

11. ->jetty -> http://localhost:8080/TSA504/start, -> the AddNew link, fill in the form, submit and ... well, it works at least for the 1-st time and new table is added into the DB... . There is a lot to be changed and tweaked here, so - let me learn a bit more about Java before continuation ;).

6. SimpleTapestry 5 CRUD application -Step 06, tweaking a grid a bit.
5. Simple Tapestry 5 CRUD application - BeanEditForm and Grid screencasts aprobation.
4. SimpleTapestry 5 CRUD application -Step 04 Adding some basic Hibernate features into the project.
3. SimpleTapestry 5 CRUD application -Step 03, "user" bean creation.
2. SimpleTapestry 5 CRUD application -Step 02, adding a service.
1. SimpleTapestry 5 CRUD application -Step 01.



2007-05-17

SimpleTapestry 5 CRUD application -Step 03, "user" bean creation.

A small lyrical digression: I'd like to follow the MVC pattern in creating the application and it's time now to add some "model" or "bean" code into the project.

After the Step 02 we already have a login page and a service for user authentication, but we still have no «user», so :
  1. Create a new class, package = org.example.TSA504.beans, name=TUser, implements Serializable, and generate the serialVersionUID field.

  2. Now, I'd like to use Hibernate with annotations and avoid boring .hbm files writing/generating, so we need to add some libraries into the project. Create a new folder TSA504\lib\ , find and copy ejb3-persistence.jar and hibernate-annotations.jar into it ( I found the files in hibernate-entitymanager-3.3.1.GA\lib\).

  3. After that, add the libraries into the project's Java Build Path:

  4. Let's start to «create» our user bean:

@Entity
@Table(name = "TUSER")
public class TUser implements Serializable {
private static final long serialVersionUID = 7769115993193444629L;
protected long id;
protected String userName;
protected String firstName;
protected String MI;
protected String lastName;
protected String email;
protected String password;
...
}

So, as you see, it's quite a simple class, you can find the listing here. Pay attention to the imports.

  1. The bean implements the Serializable interface, so we have to write equals(), hashCode() and toString() methods. Have to say honestly, I've been impressed by Appfuse project, so I've picked up a bit from there. Note, toString() realization needs commons-lang-2.3.jar, so don't forget to add the library to the project.


    6. SimpleTapestry 5 CRUD application -Step 06, tweaking a grid a bit.
    5. Simple Tapestry 5 CRUD application - BeanEditForm and Grid screencasts aprobation.
    4. SimpleTapestry 5 CRUD application -Step 04 Adding some basic Hibernate features into the project.
    3. SimpleTapestry 5 CRUD application -Step 03, "user" bean creation.
    2. SimpleTapestry 5 CRUD application -Step 02, adding a service.
    1. SimpleTapestry 5 CRUD application -Step 01.

2007-05-10

SimpleTapestry 5 CRUD application - migration from 5.0.3 to 5.0.4.

Just has moved from 5.0.3 to 5.0.4, use

mvn archetype:create -DarchetypeGroupId=org.apache.tapestry -DarchetypeArtifactId=quickstart -DarchetypeVersion=5.0.4 -DgroupId=org.example -DartifactId=TSA504 -DpackageName=org.example.TSA504 -Dversion=1.0.0-SNAPSHOT

to get the new project.

After the downloading you have to modify pom.xml – change

<tapestry-release-version>5.0.3</tapestry-release-version>

to

<tapestry-release-version>5.0.4-SNAPSHOT</tapestry-release-version>

and update Maven dependencies (I used Maven plugin for eclipse).

Now, repeat Step 01 and Step 02 for that new 5.0.4 project. All should be fine, just don't forget to change 503s to 504s.


P.S. Actually, Tapestry-User mail-list also suggests another "digit" - changing 5.0.4-SNAPSHOT just to 5.0.4 - and it works.


2007-05-09

SimpleTapestry 5 CRUD application -Step 02, adding a service.

Assuming Step 01, let's change Login page class a bit. Find and uncomment following lines with the «// Don't need this for now.»:

@Inject
private UserAuthenticator _authenticator;

and

if (!_authenticator.isValid(_userName, _password))

Then, just delete the line

if (!_userName.equals(_password))

So, here is the result , our new Login.java.

At this moment we have UserAuthenticator undefined, so let's create it – select NEW->Interface ->package = org.example.TSA503.services.interfaces, name= UserAuthenticator . The interface body is simple:

public interface UserAuthenticator {
public
boolean isValid(String userName, String pwd);
}

Now, we have to create implementation of the interface, UserAuthenticatorImpl class – NEW-Class->package=org.example.TSA503.services, name=UserAuthenticatorImpl , implements UserAuthenticator of course.

The code is also simple:

public class UserAuthenticatorImpl implements UserAuthenticator {
public boolean isValid(String userName, String pwd) {
if (userName.equalsIgnoreCase(pwd)){
return true;
}
return false;
}
}

Open your Login.java and add such an import: org.example.TSA503.services.interfaces.UserAuthenticator

Save the project and run it on jetty, open the link http://localhost:8080/TSA503/login and ...

something wrong, just because

java.lang.ClassNotFoundException: caught an exception while obtaining a class file for org.example.TSA503.pages.Login

can't be a Login page. So, let's do some additional work and notify Tapestry about our UserAuthenticator service, open /TSA503/src/main/java/org/example/TSA503/services/AppModule.java and append following to it:

public static UserAuthenticator buildUserAuthenticator()
{
return new UserAuthenticatorImpl();
}

Also, add such an import:

import org.example.TSA503.services.interfaces.UserAuthenticator;

And now - run the jetty again and open http://localhost:8080/TSA503/login - it must be fine at this time, so you can «test» the page, who knows, it may contains a lot of bugs.


6. SimpleTapestry 5 CRUD application -Step 06, tweaking a grid a bit.
5. Simple Tapestry 5 CRUD application - BeanEditForm and Grid screencasts aprobation.
4. SimpleTapestry 5 CRUD application -Step 04 Adding some basic Hibernate features into the project.
3. SimpleTapestry 5 CRUD application -Step 03, "user" bean creation.
2. SimpleTapestry 5 CRUD application -Step 02, adding a service.
1. SimpleTapestry 5 CRUD application -Step 01.