Sunday, March 6, 2011

Struts2, Tiles2, Spring, Hibernate, JQuery plugin - Using TreeView

Disclaimer:
All the software applications that appear below represent trademarks and they are the property of their respective owners.
Use and implement my notes in this article at your own risk.

Discussion here:
1. General Considerations
2. Prerequisites
3. JQuery TreeView
5. TreeViewBean;
6. Struts 2 actions;
7. DAOs;
8. Annotated Hibernate entities;

1. General Considerations:
This sample is purposed to show how to use the JQuery treeView; the 3 autocompleters will represent records from the tables "zone", "country", "city" of the "blog" database.
The sample will be presented somehow in a "top-down" fashion, ie. starting from View, then Controller, then Model components of the MVC web app architecture.

NOTE: if you don't know for example what is "blog" database, or other aspects, then you should read the "Struts2, Tiles2, Spring, Hibernate, JQuery plugin - General Considerations", which is used as a basis for this sample.

2. Prerequisites:
Make sure you have read the "Struts2, Tiles2, Spring, Hibernate, JQuery plugin - General Considerations", and installed and configured all that is written there;

3. JQuery TreeView:
The JQuery treeView refers to the rendered tree object which is offered by the JQuery javaScript libraries: jquery.cookie.js, jquery.treeview.js, jquery.treeview.async.js.
In order to use this plugin, you will have to include the following lines in your JSP file:
<<
<script src="js/jquery.cookie.js" type="text/javascript"></script>
<script src="js/jquery.treeview.js" type="text/javascript"></script>
<script src="js/jquery.treeview.async.js" type="text/javascript"></script>

>>
Thus, you made the JQuery treeView available to be used in your JSP file.

An definition of the JQuery treeView will look like:
<<
        <ul id="tree" class="filetree treeview"></ul>
>>

To populate the treeView by using Struts Actions, you should write this javaScript code (be sure the HTML element "<ul id=tree />" is already rendered):
<<
    $("#tree").treeview({
        url: "selectTree.action"
    })

>>
In our case, the tree will contain all data from zones, countries, cities and will be populated using results from "selectTree.action".

4. TreeViewBean:
This bean is used as a structure to store an element of the treeView. This element maybe a node or a leaf, in other words, there are elements that have children and other that don't have.
The structure of a treeView element contains:
<<
    String id;
    String text;
    Boolean expanded;
    String classes;
    Boolean hasChildren;
    String href;
    List<TreeViewBean> children;

>>

The bean is used in a recursive way, ie a child will have the same fields in its structure. In our case, zones has countries as children and countries has cities as children.
NOTE: the "href" TreeView field was added by me in "jquery.treeview.async.js", so, remove it if you get some error with the original "jquery.treeview.async.js".

6. Struts 2 Actions:
A JQuery treeView uses JSON as source.
So, the Struts action should return a JSON type result.
To be sure of this, you have to include this annotation to your struts action:
<<
@ParentPackage("blog-json")
>>
This will use the Struts "blog-json" package defined in struts.xml, ie. it will extend the "json-default" package of the Struts2; "json-default" uses "struts2-json-plugin-2.2.1.jar" to render a JSON result.

To populate for example the zones, you will use this code:
<<
    @Override
    @Action(value="/selectTree", results={
        @Result(name="success", type="json", params={"root","treeList"}),
        @Result(name="input", location="/jsp/empty.jsp")
    })
    public String execute() {
        try {
            List<Zone> zonesList = (List<Zone>)zoneDAO.findAll();
            List<TreeViewBean>zones = new ArrayList<TreeViewBean>();
            if (zonesList != null && !zonesList.isEmpty())
            for (Zone zone : zonesList) {
                List<Country> countriesList = (List<Country>)countryDAO.findByCriteria("zone.cod", zone.getCod());
                List<TreeViewBean>countries = new ArrayList<TreeViewBean>();
                if (countriesList != null && !countriesList.isEmpty())
                for (Country country : countriesList) {
                    List<City> citiesList = (List<City>)cityDAO.findByCriteria("country.cod", country.getCod());
                    List<TreeViewBean>cities = new ArrayList<TreeViewBean>();
                    if (citiesList != null && !citiesList.isEmpty())
                    for (City city : citiesList) {
                        cities.add(new TreeViewBean(String.valueOf(city.getId()), city.getName(), true, "file", "/blogtree/index?city_id=" + city.getId()));
                    }
                    countries.add(new TreeViewBean(country.getCod(), country.getName(), true, "important", cities));
                }
                zones.add(new TreeViewBean(zone.getCod(), zone.getName(), true, "folder", countries));
            }
            setTreeList(zones);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return ActionSupport.INPUT;
        }
        return ActionSupport.SUCCESS;
    }


>>

Here:
"treeList" is the Java List which will be rendered as a JSON object;
"zoneDAO", "countryDAO and cityDAO are the DAO (see "6. DAOs") managed by Spring over the Hibernate entities which contains methods as "findByCriteria()" in order to obtain data from database;

Also, you may observe here annotations to define the "success" and "input" results (overcomes) of the action "selectTree".

In the same action you should define getters and setters for "List<KeyValuePairBean> treeList".

NOTE: to see how the Struts 2 Actions are accessed, and how their results are rendered, checkout also the "struts.xml" and "tiles.xml" files.

7. DAOs
DAOs, namely Data Access Objects, are used by Spring to obtain data from database via Hibernate.
DAOS are part of the business layer of a database web app.
A DAO class extends in this case the "HibernateDaoSupport" and contains methods to access the database via annotated Hibernate entities.
Any DAO should be described as a bean in the "applicationContext.xml" file in order to be seen by the sessionFactory; for example, for zones:
<<
    <bean id="ZoneDAO" class="blog.hibernate.dao.ZoneDAO">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>

>>

From Java point of view, a DAO should use a session manager, in this case, "HibernateDaoSupport" which is a Spring class that manages Hibernate sessions over annotated entities.
NOTE: a method that uses Hibernate session to get data from database uses HQL (Hibernate Query Language); to understand the HQL syntax you should google for HQL documentation.

8. Annotated Hibernate entities
An annotated entity is a POJO class that describes a database table by means of annotations.
It represents the Model from the MVC architecture.
For example, for the database table "zone", it was defined the Zone.java entity class; to refer table "zone" from database "blog", annotations are placed at the top of the class definition:
<<
@Entity
@Table(name = "zone", catalog = "blog")

>>
, while for each of table "zone" fields, there are specified on their value getters: primary key, foreign key, column name, field length, aso, if they exist.
Here are some examples of annotations, taken from Zone.java:
<<
    @Id
    @GeneratedValue
    @Column(name = "cod", unique = true, nullable = false, length = 4)

>>
<<
    @Column(name = "name", nullable = false, length = 45)
>>
<<
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "zone")
>>

NOTE: if MyEclipse is used as IDE, you may generate both DAO and entity for each table by using Hibernate Reverse Engineering perspective.

23 comments:

  1. This looks like a clean integration of tree and dao. Could you post the source ?

    ReplyDelete
    Replies
    1. Nice tutorial. Can you please post the source code to syam_pad@gmail.com.

      Regards
      Syam

      Delete
    2. Nice tutorial.can you send me the source code please to syam_pad@yahoo.com.

      Delete
    3. Can you post the source code please? Here is my email I'd syam_pad@yahoo.com

      Delete
  2. I can send it to you if you give me an email address. However, you must have installed all the libraries form the "general considerations".

    ReplyDelete
  3. Thanks this helped me alot

    can you please provide me with the source code ? kittaneh@gmail.com

    ReplyDelete
  4. can you please provide me with the source code ? jksjava@gmail.com

    ReplyDelete
  5. Please send me the source code including the libraries to aficionado@aol.in

    ReplyDelete
  6. @aficionado: I sent you the code for this sample. Unfortunately, I cannot send you all the librairies I used because of their size: 550MB; also, they do not represent my work.

    ReplyDelete
  7. hi vsorinel happy new year 2012..we are doing project based on struts2 jquery grid.. i have one doubt regarding grid column... when i want to add or edit a new rows in grid,i want to display city list in select option based on country and area list based on city..can u please help me to get the solution..my email id is maniblue6@gmail.com

    ReplyDelete
  8. @maniblue: hi, your question refers to jqGrid, more specifically to sjg:gridColumn element, where sjg prefix refers struts-jquery-grid-tags. In this type of element you are able to put a select html-like element (see the edittype property of sjg:gridColumn). I cannot help you because of limited time, but you have a startpoint here:
    http://vsorinel.blogspot.com/2011/03/struts2-tiles2-spring-hibernate-jquery_1981.html

    ReplyDelete
  9. please, may you send me source? zhan_mels@mail.ru

    ReplyDelete
  10. Please send me the source code of it.
    My email id is arati.shri3@gmail.com

    ReplyDelete
  11. hi please send me source code to my email id(ramanareddyu@gmail.com)

    ReplyDelete
  12. In fact I would also appreciate you could send me the source code... my e-mail is etsat@portugalmail.pt
    If you got any problem with attachment kindly let me know.
    Thanks a lot for your help.

    ReplyDelete
  13. hi nice post,please send the source code to vasuonweb@gmail.com

    ReplyDelete
  14. please can u mail me the source code plsss(xyzabc647@gmail.com)

    ReplyDelete
  15. please please mail me the source code(xyzabc647@gmail.com)

    ReplyDelete
  16. hi can you please send source code to nivassri29@gmail.com

    ReplyDelete
  17. Hi all,
    I know there were guys that wanted the code and probably I couldn't send them the code in useful time. First of all I want to apologize to all these guys.
    Second, due to latest activity, I really have no time to maintain this blog, so I want you guys understand I CANNOT SEND THE CODE ANYMORE.
    In this case, you have 2 solutions:
    1) the main aspects for each sample are already posted on respective topics; practically, if you read the "general considerations" and the related topics, you will not need the code; you just need to configure a new app and paste there the code from the topics;
    2) if you really want the code, then ALL THE GUYS THAT PUT THEIR EMAILS ON THE COMMENTS ABOVE HAVE RECEIVED THE CODE; so, if I cannot respond, then maybe they can ;) in fact, it is a distributable code, isn't it ? ;)
    I hope you guys understand the above, thanx, vsorinel.

    ReplyDelete