2007-09-20

SimpleTapestry 5 CRUD application - Step 08, Simple authentication

To be updated.
I'd like to make some page "protected" i.e. if a user hasn't been logged in then such a page must not be displayed. The solution was found here:

T5 - Authentication filter

T5:Login and session

So, I added one new page class (abstract), LoginProtected it should serve as a base for all "protected" pages:

//incomplete listing
public abstract class LoginProtected {
@ApplicationState
private SessionData _session;

Object onActivate() {
if(!_session.isSessionExists()){
return "Login";
}
return null;
}


SessionData is a "value" object to store userName and sessionExists flag between pages, so if a session doesn't exist then user will be redirected to Login page.

Also, I changed the Home page, now it extends LoginProtected:
public class Home extends LoginProtected {

Another change - Login.java, new private variable _session was added, see the code.

So, now, if a user tries to open /home page without logging in , the navigation will go to the Login page.

8. Step 08, Simple authentication
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-07-21

SimpleTapestry 5 CRUD application - renaming (refactoring) and migration to 5.0.5.

Migration from T5.0.4 to T5.0.5:

Please archive your project before the action!

1. pom.xml, find the line
<tapestry-release-version>5.0.4</tapestry-release-version>
and cnange it to
<tapestry-release-version>5.0.5

2. Right click menu->Maven2->Update Source Folder;
3. After 2. the project in Eclipse was shown as full or errors ->Open project's properties and add all libraries into classpath (Java Build Path). Remember about javax.servlet.jar (Step 06);
4. After 3. - the were still several errors in the project, org.apache.tapestry... were not resolved, I tried "dance with a tambourine" approach: Maven2 Clean/Build commands etc but it didn't work. So, had to build a new T5 quick-start project with help of

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

And that didn't help also... .
So, I just deleted the project from Eclipse and from disk.
5. Restored the project from the archive and imported in in Eclipse again, repeated 1,2,3 and now it even compiles!

I also renamed the project from TSA504 to just TSA.

2007-06-19

SimpleTapestry 5 CRUD application -Step 07, Cancel button, variant 1.

Added "Cancel" button on AddNew page:

1.Turned off client validation:
AddNew.html, <form t:id="regform" t:clientValidation="false">
2.
AddNew.html, added <input t:type="submit" value="Cancel" t:id="Cancel"/>
3. AddNew.java, added
private String _pageToReturn;
------------------------------------
String onSuccess() {
if (_pageToReturn!=null){return _pageToReturn;}...
------------------------------------
void onSelectedFromCancel(){
_regform.clearErrors();
_pageToReturn = "Start";
}

Of course, there should be a better way... Let me search or drop a ray of light, if you have one :).

8. Step 08, Simple authentication

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-06-11

SimpleTapestry 5 CRUD application -Step 06, tweaking a grid a bit.

Added several modifications into the files:

1. Home page grid doesn't show the PWD column any more (but BeanEditForm example page (UpdateExisting) does), it's made by using/correcting the "model" attribute of "Grid" in Home.java:

//Inspired by http://tapestry.apache.org/tapestry5/tapestry-core/guide/beaneditform.html
void pageLoaded()
{
_model = _beanModelSource.create(TUser.class, true, _resources);
_model.remove("password");
}
and Home.html

<table t:type="grid" rowsPerPage="5" row="tUser" source="usersList" model="model">

2.
I renamed Registration page to UpdateExisting, it's now used for displaying and editing data of existing users - from Home page click a user name in the grid to get his/her details available for editing. onActivate()+ onPassivate() approach is used:

UpdateExisting.java


Home.html changes:
<table t:type="grid" rowsPerPage="5" row="tUser" source="usersList" model="model">
<t:parameter name="usernameCell">
<a t:type="PageLink" t:page="UpdateExisting" context="tUser.userName">${tUser.userName}</a>
</t:parameter>
</table>

3. UpdateExisting.html was changed to show "password" field values as PasswordFied type (i.e. hidden by *****):

<form t:type="BeanEditForm" object="tUser" submitLabel="Update">
<t:parameter name="password">
<t:label for="password"/>
<t:passwordfield t:id="password" value="tUser.password"/>
</t:parameter>
</form>

4. Added UTF-8 support, thanks to HowTo. A probable issue here is AppModule.java, IDE complains on new UTF_8 code. It was resolved by adding \jetty-5.1.7\lib\javax.servlet.jar into the classpath.



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