Wednesday, December 31, 2014

Spring4 / Hibernate4 / JSF2 / Primefaces5 jee web application skull

In this article we will try to build an entire skull of jsf2/spring4 application, welwill use hibernate4 to manage persistency, use bundles for internalization and primefaces 5 in view layer.The application will be mavenized.


The result architecture will have this behavior:



  1. First Step is to create a maven project based on webapp archtype

    1
    mvn archetype:generate -DgroupId=com.itillusion.travel -DartifactId=travel -Dpackagename=com.itillusion.travel -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeVersion=1.0 -DinteractiveMode=false
    (how to work with maven nad elipse ?
     this link is useful by A.Mekki)
  2. Next step is to add correct dependencies for artifacts that we'll use.to our pom.xml

    MySQL jdbc connector
    Hibernate4 (requires dbcp2)
    Spring4
    Primefaces5
    JSF 2 api/impl and servlet

    we will add also repositories
    our pom.xml will be


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
      <modelversion>4.0.0</modelversion>
      <groupid>com.itillusion</groupid>
      <artifactid>travel</artifactid>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>war</packaging>
       
      <properties>
      <spring .framework.version="">4.1.3.RELEASE</spring
      <spring .security.version="">3.2.5.RELEASE</spring>
      <hibernate .framework.version="">4.3.7.Final</hibernate>
      <primefaces .framework.version="">5.1</primefaces>
     </properties>
      
     
     <dependencies>
      
      <!-- MySQL -->
      <dependency>
       <groupid>mysql</groupid>
       <artifactid>mysql-connector-java</artifactid>
       <version>5.1.6</version>
      </dependency>
      <!-- MySQL -->
      
      
      <!-- Hibernate -->
      <dependency>
         <groupid>org.hibernate</groupid>
         <artifactid>hibernate-core</artifactid>
         <version>${hibernate.framework.version}</version>
       </dependency>
      <!-- Hibernate -->
       
      <!-- Primefaces -->
      <dependency>
       <groupid>org.primefaces</groupid>
       <artifactid>primefaces</artifactid>
       <version>${primefaces.framework.version}</version>
      </dependency>
      <!-- /Primefaces -->
       
      <!-- Spring framework -->
      <dependency>
       <groupid>org.springframework</groupid>
       <artifactid>spring-context</artifactid>
       <version>${spring.framework.version}</version>
      </dependency>
      <dependency>
       <groupid>org.springframework</groupid>
       <artifactid>spring-web</artifactid>
       <version>${spring.framework.version}</version>
      </dependency>  
      <dependency>
       <groupid>org.springframework</groupid>
       <artifactid>spring-orm</artifactid>
       <version>${spring.framework.version}</version>
      </dependency>
       
      <!-- Spring framework -->
       
      <!-- Jsf -->
      <dependency>
       <groupid>com.sun.faces</groupid>
       <artifactid>jsf-api</artifactid>
       <version>2.1.2</version>
      </dependency>
      <dependency>
       <groupid>com.sun.faces</groupid>
       <artifactid>jsf-impl</artifactid>
       <version>2.1.2</version>
      </dependency>
      <!-- Jsf -->
       
      <!-- Servlets -->
      <dependency>
       <groupid>javax.servlet</groupid>
       <artifactid>servlet-api</artifactid>
       <version>2.5</version>
       <scope>provided</scope>
      </dependency>
      <!-- Servlets --> 
       
        
      <!-- apache dbcp -->
             <dependency>
           <groupid>org.apache.commons</groupid>
           <artifactid>commons-dbcp2</artifactid>
           <version>2.0</version>
       </dependency>
      <!-- apache packs -->
       
      <!-- JUnit 3.8.1 -->
      <dependency>
       <groupid>junit</groupid>
       <artifactid>junit</artifactid>
       <version>3.8.1</version>
       <scope>test</scope>
      </dependency>
      <!-- JUnit 3.8.1 -->
     
      
     
     </dependencies>
      
       
       
     <repositories>
      
      <repository>
       <id>JSFRepo</id>
       <name>Repository for JSF2</name>
       <!-- <layout>default</layout>-->
      </repository>
      
      <repository>
       <id>MavenRepo</id>
       <name>Repository for Maven2</name>
       <!-- <layout>legacy</layout>-->
      </repository
       
      <repository>
       <id>prime-repo</id>
        <name>PrimeFaces Maven Repository</name>
       <layout>default</layout>
      </repository>
       
       
      <repository>
       <id>maven-repository.dev.java.net</id>
       <name>Java Dev Net Repository</name>
       <releases>
        <enabled>true</enabled>
        <updatepolicy>never</updatepolicy>
       </releases>
       <snapshots>
        <enabled>false</enabled>
       </snapshots>
      </repository>
       
      <repository>
       <id>spring-milestone</id>
       <name>Spring Portfolio Milestone Repository</name>
       </url>
      </repository>
       
      <repository>
       <id>spring-snapshot</id>
       <name>Spring Portfolio snapshot Repository</name>
      </repository>
       
      <repository>
       <id>jboss-repo</id>
       <name>jboss Repository</name>
      </repository>
       
      <repository>
       <id>java.net</id>
       <name>Java.net Repository for Maven2</name>
      </repository>
     
      <repository>
       <id>spring-ext</id>
       <name>Spring External Dependencies Repository</name>
       </url>
      </repository>
       
      <repository>
       <releases>
        <enabled>true</enabled>
       </releases>
       <snapshots>
        <enabled>false</enabled>
        <updatepolicy>never</updatepolicy>
       </snapshots>
       <id>repository.jboss.com</id>
       <name>Jboss Repository for Maven</name>
       <layout>default</layout>
      </repository>
       
       
      <repository>
       <id>jboss-public-repository-group</id>
       <name>JBoss Public Repository Group</name>
      </repository>
     </repositories>
    </project>

    Note here we have used version properties to make pom more evolutive
    in 
    1
    <spring.security.version>3.2.5.RELEASE</spring.security.version>
  3. Next step is to configure web.xml (typical jsf webapp, web.xml with listner for spring)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
      <display-name>travel</display-name>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
       
       
       <!-- Change to "Production" when you are ready to deploy -->
     <context-param>
      <param-name>javax.faces.PROJECT_STAGE</param-name>
      <param-value>Development</param-value>
     </context-param>
      
     <!-- JSF servlet mappings --> 
     <servlet>
      <servlet-name>Faces Servlet</servlet-name>
      <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
     </servlet>
     <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>*.jsf</url-pattern>
      <url-pattern>*.xhtml</url-pattern>
     </servlet-mapping>
     <!-- JSF servlet mappings -->
      
      
      
      
     <!-- spring listener -->
     <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
     </listener>
     <!-- spring listener -->
      
     <!-- spring context params -->
     <context-param>
      <param-name>contextConfigLocation</param-name>
       <param-value>/WEB-INF/applicationContext.xml</param-value>
     </context-param>
     <!-- spring context params -->
      
    </web-app>

  4. Now we write our faces-config.xml, thanks to annotation, this configuration file is too light

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
         
         
        <application>
            <locale-config>
                  <default-locale>fr</default-locale>
             </locale-config>
         <resource-bundle>
       <base-name>com.itillusion.travel.internalization.language</base-name>
       <var>language</var>
         </resource-bundle>
             
            <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
             
        </application>
    </faces-config>
    We have used here a resource-bundle to manage internalization of messages and labels:
    In this line:
    <base-name>com.itillusion.travel.internalization.language</base-name>
     we told to jsf that our file is located in package com.itillusion.travel.internalizationand its name is language.properties
      
    NB: language.properties is a resource file: it must be located under WEB-INF/classes in deployement  folder :
    here under eclipse we have configured in deployement assembly onglet  a copy of src/main/resources to WEB-INF/classes

    language.properties contains these few lines: applicationTitle=Traveler
    companyName=Itillusion
    userId=ID Utilisateur
    userName=Nom utilisateur

  5. Now we go ahead to applicationContext.xml which contains declaration of spring beans and hibernate properties.

    In order to seperate real configuration from database access configuration we will put database access informations in a separate file called  jdbc.properties under WEB-INF. folder

    We have told to spring that we will work with annotation and application beans will be in sub packages of  "com.itillusion.travel
    <context:component-scan base-package="com.itillusion.travel" />

    We have to tell hibenate where he will find models
    <property name="packagesToScan" value="com.itillusion.travel.model" />


    Here is a complete applicationContext.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
             
         
          
      <context:annotation-config>
     <context:component-scan base-package="com.itillusion.travel">
      
     <!--  Hibernate relates beans and properties -->
     <bean class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" id="sessionFactory">
      <property name="hibernateProperties">
       <props>
        <!-- <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>-->
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
        <prop key="hibernate.show_sql">true</prop>
        <prop key="hibernate.cache.use_query_cache">false</prop>
       </props>
      </property>
      <!-- entities -->
      <property name="packagesToScan" value="com.itillusion.travel.model">
      <property name="dataSource">
       <ref bean="dataSource">
      </ref></property>
     </property></bean>
     <bean class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close" id="dataSource" lazy-init="true">
      <property name="driverClassName" value="${jdbc.driverClassName}">
      <property name="url" value="${jdbc.url}">
      <property name="username" value="${jdbc.username}">
      <property name="password" value="${jdbc.password}">
      <property name="validationQuery" value="select 1 ">
      <property name="testOnBorrow" value="True">
     </property></property></property></property></property></property></bean>
      
     <!-- where are stored connexion properties(login,pwd,server,..) -->
     <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" id="propertyConfigurer">
      <property name="locations">
       <list>
        <value>/WEB-INF/jdbc.properties</value>
       </list>
      </property>
     </bean>
     <!-- /Hibernate -->
     <!-- Enable the configuration of transactional behavior based on annotations -->
        <tx:annotation-driven transaction-manager="transactionManager">
      
        <!-- Transaction Manager is defined -->
        <bean class="org.springframework.orm.hibernate4.HibernateTransactionManager" id="transactionManager">
           <property name="sessionFactory" ref="sessionFactory">
        </property></bean>
    </tx:annotation-driven></context:component-scan></context:annotation-config></beans>
    and here is the listing of jdbc.properties
    jdbc.driverClassName=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/travel
    jdbc.username=travel
    jdbc.password=yourpassword

  6. Now we have the choice : finish the view layer with its facelets or attack an entity to display it in th view layer.
    Personally i prefer finish the view for a simple reason :
    When a standard page of our application is displayed, then any problem that will appear in integration of any page will be the result of a programmation mistake.

    Ok, we continue,
    we start by th building of a template for the application:
      A- create a folder templates and under it a folder common.



    B- Create the commonLayout.xhtml file that will descibe the design of a common page in the application, in our casse commonLayout is composed by 3 files a header, a content and a footer  (here we have a one column deisgn).

    here is the listing of the 4 files:

    commonLayout.xhtml:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
        <h:head>
      <h:outputstylesheet library="css" name="common-style.css">
        </h:outputstylesheet></h:head>
      
        <h:body>
      
     <div id="page">
      
         <div id="header">
      <ui:insert name="header">
        <ui:include src="commonHeader.xhtml">
      </ui:include></ui:insert>
         </div>
    <div id="content">
        <ui:insert name="content">
         <ui:include src="commonContent.xhtml">
         </ui:include></ui:insert>
         </div>
    <div id="footer">
          <ui:insert name="footer">
            <ui:include src="commonFooter.xhtml">
          </ui:include></ui:insert>
             </div>
    </div>
    </h:body>
    commonHeader.xhtml:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
         
         <ui:composition>
         <!-- common header -->
          <div class="head-panel">
           <div class="application-logo">
            <h:form>
             <p:graphicimage styleclass="logo-img" value="/resources/img/common/traveler.jpg">
            </p:graphicimage></h:form>
           </div>
    <div class="slogon">
    #{language.applicationTitle}</div>
    <div class="time-panel">
         <h:form>
             <p:clock mode="server" pattern="dd.MM.yyyy HH:mm:ss">
         </p:clock></h:form>
        </div>
    </div>
    <!-- /common header -->
        <!-- menu  -->
        <div class="menu-panel">
         <h:form
            <p:growl id="messages">
          
            <p:menubar>
                <p:submenu icon="ui-icon-document" label="File">
                    <p:submenu icon="ui-icon-contact" label="New">
                        <p:menuitem url="#" value="Project">
                        <p:menuitem url="#" value="Other">
                    </p:menuitem></p:menuitem></p:submenu>
                    <p:menuitem url="#" value="Open">
                    <p:separator>
                    <p:menuitem url="#" value="Quit">
                </p:menuitem></p:separator></p:menuitem></p:submenu>
          
                <p:submenu icon="ui-icon-pencil" label="Edit">
                    <p:menuitem icon="ui-icon-arrowreturnthick-1-w" url="#" value="Undo">
                    <p:menuitem icon="ui-icon-arrowreturnthick-1-e" url="#" value="Redo">
                </p:menuitem></p:menuitem></p:submenu>
          
                <p:submenu icon="ui-icon-help" label="Help">
                    <p:menuitem url="#" value="Contents">
                    <p:submenu icon="ui-icon-search" label="Search">
                        <p:submenu label="Text">
                            <p:menuitem url="#" value="Workspace">
                        </p:menuitem></p:submenu>
                        <p:menuitem url="#" value="File">
                    </p:menuitem></p:submenu>
                </p:menuitem></p:submenu>
          
                <p:submenu icon="ui-icon-gear" label="Actions">
                    <p:submenu icon="ui-icon-refresh" label="Ajax">
                        <p:menuitem actionlistener="#{menuView.save}" icon="ui-icon-disk" update="messages" value="Save">
                        <p:menuitem actionlistener="#{menuView.update}" icon="ui-icon-arrowrefresh-1-w" update="messages" value="Update">
                    </p:menuitem></p:menuitem></p:submenu>
                    <p:submenu icon="ui-icon-newwin" label="Non-Ajax">
                        <p:menuitem actionlistener="#{menuView.delete}" ajax="false" icon="ui-icon-close" update="messages" value="Delete">
                    </p:menuitem></p:submenu>
                </p:submenu>
          
                <p:menuitem icon="ui-icon-close" url="http://www.primefaces.org" value="Quit">
          
                <f:facet name="options">
                    <p:inputtext placeholder="Search" style="margin-right: 10px;">
                    <p:commandbutton icon="ui-icon-extlink" type="button" value="Logout">
                </p:commandbutton></p:inputtext></f:facet>
            </p:menuitem></p:menubar>
        </p:growl></h:form>
        </div>
    <!-- /menu -->
         </ui:composition>
        

    commonContent.xhtml:
    1
    2
    3
    4
    5
    6
    7
    8
         
         <ui:composition>
          <ui:insert name="content">
           <h1>
    This is default content</h1>
    </ui:insert>
         </ui:composition>
        

    1
    2
    3
    4
    5
    6
    7
    8
         
         <ui:composition>
      
       <div class="footer-panel">
        Traveler v1.0- (C) <a href="http://www.itillusion.com/">IT ILLUSION</a> -2014-
       </div>
    </ui:composition>
        

    Note that next the composition called content in the commonContent.xhtml will be overrided each time a page is shown
    C- add the index.jsp page that will redirect to a default xhtml page that will be considered a the entry point of the application.
    index.jsp under the root(webapp):
    1
    <jsp:forward page="faces/editUsers.xhtml"></jsp:forward>

    our application will show directly a listing of users inserted previously in database.
    css and js files have to be under folder resources under webapp otherways they will not be loaded.
  7. Now we will create the different layers of the application:
    a model layer
    a dao layer
    a service layer
    a managedbeans layer to interact with jsf views

    Considering that we have a mysql 3 tables under schema travel with this descriptions:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    mysql>  show tables;
    +------------------+
    | Tables_in_travel |
    +------------------+
    | profile          |
    | user_profile     |
    | utilisateur      |
    +------------------+
    3 rows in set (3.36 sec)
     
     
    mysql> describe utilisateur;
    +-----------+-------------+------+-----+---------+----------------+
    | Field     | Type        | Null | Key | Default | Extra          |
    +-----------+-------------+------+-----+---------+----------------+
    | usr_id    | int(11)     | NO   | PRI | NULL    | auto_increment |
    | usr_login | varchar(45) | YES  |     | NULL    |                |
    | usr_pwd   | varchar(45) | YES  |     | NULL    |                |
    +-----------+-------------+------+-----+---------+----------------+
    3 rows in set (2.76 sec)
     
    mysql> desc profile;
    +---------+-------------+------+-----+---------+----------------+
    | Field   | Type        | Null | Key | Default | Extra          |
    +---------+-------------+------+-----+---------+----------------+
    | prf_id  | int(11)     | NO   | PRI | NULL    | auto_increment |
    | prf_lib | varchar(45) | NO   | UNI | NULL    |                |
    +---------+-------------+------+-----+---------+----------------+
    2 rows in set (0.28 sec)
     
    mysql> desc user_profile;
    +---------------+---------+------+-----+---------+----------------+
    | Field         | Type    | Null | Key | Default | Extra          |
    +---------------+---------+------+-----+---------+----------------+
    | usrprf_id     | int(11) | NO   | PRI | NULL    | auto_increment |
    | prf_id        | int(11) | NO   | MUL | NULL    |                |
    | usr_id        | int(11) | NO   | MUL | NULL    |                |
    | usrprf_active | int(11) | NO   |     | 0       |                |
    +---------------+---------+------+-----+---------+----------------+
    4 rows in set (2.53 sec)
  8. Model layer (just one class (utilisateur))

    Note we will this tree of packages and classes


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    package com.itillusion.travel.model;
     
    // Generated 25 nov. 2014 14:54:59 by Hibernate Tools 3.4.0.CR1
     
    import java.util.HashSet;
    import java.util.Set;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import static javax.persistence.GenerationType.IDENTITY;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;
     
    /**
     * Utilisateur generated by hbm2java
     */
    @Entity
    @Table(name = "utilisateur", catalog = "travel")
    public class Utilisateur implements java.io.Serializable {
     
     /**
      *
      */
     private static final long serialVersionUID = 8276067938930706574L;
     private Integer usrId;
     private String usrLogin;
     private String usrPwd;
     private Set<userprofile> userProfiles = new HashSet<userprofile>(0);
     
     public Utilisateur() {
     }
     
     public Utilisateur(String usrLogin, String usrPwd,
       Set<userprofile> userProfiles) {
      this.usrLogin = usrLogin;
      this.usrPwd = usrPwd;
      this.userProfiles = userProfiles;
     }
     
     @Id
     @GeneratedValue(strategy = IDENTITY)
     @Column(name = "usr_id", unique = true, nullable = false)
     public Integer getUsrId() {
      return this.usrId;
     }
     
     public void setUsrId(Integer usrId) {
      this.usrId = usrId;
     }
     
     @Column(name = "usr_login", length = 45)
     public String getUsrLogin() {
      return this.usrLogin;
     }
     
     public void setUsrLogin(String usrLogin) {
      this.usrLogin = usrLogin;
     }
     
     @Column(name = "usr_pwd", length = 45)
     public String getUsrPwd() {
      return this.usrPwd;
     }
     
     public void setUsrPwd(String usrPwd) {
      this.usrPwd = usrPwd;
     }
     
     @OneToMany(fetch = FetchType.LAZY, mappedBy = "utilisateur")
     public Set<userprofile> getUserProfiles() {
      return this.userProfiles;
     }
     
     public void setUserProfiles(Set<userprofile> userProfiles) {
      this.userProfiles = userProfiles;
     }
     
    }
     
    </userprofile></userprofile></userprofile></userprofile></userprofile>
  9. Dao layer, all classes under com.itillusion.travel.dao are interfaces, who knows if we will change hibernate by another orm ?
    implementations are under com.itillusion.travel.dao.impl
    First of all web begin with generic dao classes: GenericDao.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package com.itillusion.travel.dao;
     
    import java.io.Serializable;
    import java.util.List;
     
     
    public interface GenericDao<t extends="" i="" serializable=""> {
        public T find(I id);
        public List<t> findAll();
        public void delete(T obj);
        public void saveOrUpdate(T obj);
    }
    </t></t>
    an implementation of this class is
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    package com.itillusion.travel.dao.impl;
     
    import java.io.Serializable;
    import java.util.List;
     
    import org.hibernate.SessionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.transaction.annotation.Transactional;
     
    import com.itillusion.travel.dao.GenericDao;
     
     
    public abstract class GenericDaoImpl<t extends="" i="" serializable=""> implements GenericDao<t i="">{
     
     
        @Autowired
         SessionFactory sessionFactory;
         
        private Class<t> type;
         
        public GenericDaoImpl(Class<t> type){
         this.type = type;
        }
        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        }
         
        public SessionFactory getSessionFactory() {
            return sessionFactory;
        }
     
     @SuppressWarnings("unchecked")
     @Transactional(readOnly = true)
        @Override
        public T find(I id) {
            return (T) getSessionFactory().getCurrentSession().get(type, id);
        }
     
         
        @SuppressWarnings("unchecked")
     @Transactional(readOnly = true)
        public List<t> findAll(){
          
         return (List<t>) getSessionFactory().getCurrentSession().createQuery("from "+type.getName()).list();    
            
        }
         
        @Transactional
        @Override
        public void delete(T obj) {
            getSessionFactory().getCurrentSession().delete(obj);
        }
     
        @Transactional
        @Override
        public void saveOrUpdate(T obj) {
            getSessionFactory().getCurrentSession().saveOrUpdate(obj);
        }
    }
    </t></t></t></t></t></t>
    NB: this class is under impl subpackage.
    @Autowired annotation is present to ensure the injection of sessionFactory bean
    Now wel will create an interface for UserDao ; here we don't need anything expect methods in GenericDao
    1
    2
    3
    4
    5
    6
    7
    8
    9
    package com.itillusion.travel.dao;
     
    import com.itillusion.travel.model.Utilisateur;
     
    public interface UserDao extends GenericDao<utilisateur nteger=""> {
     
    }
     
    </utilisateur>

    a possible implementation for this interface is
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package com.itillusion.travel.dao.impl;
     
    import org.springframework.stereotype.Repository;
    import com.itillusion.travel.dao.UserDao;
    import com.itillusion.travel.model.Utilisateur;
     
    @Repository
    public class UserDaoImpl extends GenericDaoImpl<utilisateur nteger=""> implements UserDao {
     
     public UserDaoImpl(){
      super(Utilisateur.class);
     }
     public UserDaoImpl(Class<utilisateur> type) {
      super(type);
     }
     
    }
    </utilisateur></utilisateur>
    Note the presence og @Repository annotation it's needed for dao bean injection in service bean
    Ok now we have set the Dao layer.
  10. We pass to service layer: same idea it will be interfaces for eache service and one/many implementation for each interface
    let's start with user interface
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package com.itillusion.travel.service;
     
    import java.util.List;
     
    import com.itillusion.travel.model.Utilisateur;
    //since we willl only display list of users
    public interface UserService {
      
     public List<utilisateur> getUsers();
      
     
    }
    </utilisateur>

    a possible implementation for this interface is
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    package com.itillusion.travel.service.impl;
     
     
    import java.util.List;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import com.itillusion.travel.dao.UserDao;
    import com.itillusion.travel.model.Utilisateur;
    import com.itillusion.travel.service.UserService;
     
    @Service
     
    public class UserServiceImpl implements UserService {
     
     @Autowired
     UserDao userDao;
      
     @Override
     public List<utilisateur> getUsers() {
      return userDao.findAll();
       
     }
     
     public UserDao getUserDao() {
      return userDao;
     }
     
     public void setUserDao(UserDao userDao) {
      this.userDao = userDao;
     }
     
    }
     
    </utilisateur>
    Note the presence of @Service annotation needed for service object injection in the managed bean
  11. Last step is to create our managedbean !
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    package com.itillusion.travel.beans;
     
    import java.io.Serializable;
    import java.util.List;
    import javax.annotation.PostConstruct;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.SessionScoped;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
     
    import com.itillusion.travel.model.Utilisateur;
    import com.itillusion.travel.service.UserService;
      
    @Component
    @ManagedBean(name="listUsersBean")
    @SessionScoped
     
    public class ListUsersBean implements Serializable {
         
              
     
     
     /**
      *
      */
     private static final long serialVersionUID = 6675856254221490117L;
     
     @Autowired
        private UserService authService;
         
        private List<utilisateur> users;
          
        @PostConstruct
        public void init() {
         System.out.println(authService);
            users = authService.getUsers();
        }
     
     public List<utilisateur> getUsers() {
      return users;
     }
     
     public void setUsers(List<utilisateur> users) {
      this.users = users;
     }
     
     public UserService getAuthService() {
      return authService;
     }
     
     public void setAuthService(UserService authService) {
      this.authService = authService;
     }
      
         
       
    }
    </utilisateur></utilisateur></utilisateur>
  12. We will now display all users :), then we will return to our application and we will create a folder called faces under the webapp and create our xhtml page editUsers.xhtml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    <h:body>
     
     <ui:composition template="../templates/common/commonLayout.xhtml">
    <ui:define name="content">
    <!-- Specific content -->
      <h:form>
        <p:datatable id="tbl" paginator="true" paginatortemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {Exporters}" rows="10" style="margin-bottom: 20px;" value="#{listUsersBean.users}" var="user">
      
            <f:facet name="{Exporters}">
                <h:commandlink>
                    <p:graphicimage value="/resources/img/tools/excel.png" width="24">
                    <p:dataexporter filename="users" target="tbl" type="xls">
                </p:dataexporter></p:graphicimage></h:commandlink>
      
                <h:commandlink>
                    <p:graphicimage value="/resources/img/tools/pdf.png" width="24">
                    <p:dataexporter filename="users" target="tbl" type="pdf">
                </p:dataexporter></p:graphicimage></h:commandlink>
      
                <h:commandlink>
                    <p:graphicimage value="/resources/img/tools/csv.png" width="24">
                    <p:dataexporter filename="users" target="tbl" type="csv">
                </p:dataexporter></p:graphicimage></h:commandlink>
      
                <h:commandlink>
                    <p:graphicimage value="/resources/img/tools/xml.png" width="24">
                    <p:dataexporter filename="users" target="tbl" type="xml">
                </p:dataexporter></p:graphicimage></h:commandlink>
            </f:facet>
      
            <p:column>
                <f:facet name="header">
                    <h:outputtext value="#{language.userId}">
                </h:outputtext></f:facet>
                <h:outputtext value="#{user.usrId}">
            </h:outputtext></p:column>
      
            <p:column>
                <f:facet name="header">
                    <h:outputtext value="#{language.userName}">
                </h:outputtext></f:facet>
                <h:outputtext value="#{user.usrLogin}">
            </h:outputtext></p:column>
      
        </p:datatable>
    </h:form>
      
     <!-- End specific content -->
     </ui:define>
     </ui:composition>
     
    </h:body>
  13. we have that then :

    just a remark; if you want to use primefaces themes or skins
    - go to this url -

  14. comments are welcome!

Friday, November 21, 2014

how debug jsf/j2ee web application

to debug jsf application or a j2ee web application, you can set PROJECT_STAGE context parameter to Developement like this (in the web.xml file):
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>


you can turn this parameter to Production to stop debug. 

Saturday, July 12, 2014

[Problème] 404 - Component not found (joomla 3 back office)

This article is for joomla components / modules developers.
Usually you have this error when trying to run/configure your joomla 2.5 component on joomla 3.x plateform.
This error is due to non 100% compatibility of 2.5 components with joomla 3.x
For some simple components proceed as follows :
  1. In every file that references DS variable
    put at the begin :
    if(!defined('DS')) define('DS', DIRECTORY_SEPARATOR);
  2. rename admin.your_component.php file in admin section to your_component.php
  3. Change each JController or JView classes reference to JControllerLegacy or JViewLegacy
  4. Don't forget to do that to the 2 sections site and admin

This link may be useful

Thursday, June 26, 2014

Jquery ready function and problems with media queries

yesterday i have faced a problem
i had  to make a design responsive according to a psd
i've found that some blocks that were injected by jquery thanks to
1
2
3
4
5
6
7
8
9
$(".yourdiv").append(.....)<br>
jQuery(function(){<br>
if($window.width()<768)<br>
{<br>
     $("#mydiv").appendTo("#block1");<br>
}else{<br>
         $("#mydiv").appendTo("#block2");<br>
}<br>
}<br>
and mydiv had two styles
1
2
3
4
5
6
@media screen and (max-width: 767px){<br>
    #mydiv STYLE1<br>
}<br>
@media screen and (min-width: 768px){<br>
    #mydiv STYLE2<br>
}<br>
i found that mydiv had the style 2 and was the child of block 1 which is incorrect for me

finally it was wrong to use jQuery(function(){} which fires before application of media queries
i've used modernizr library
with this hack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(function($){
 
    function doneResizing() {
 
        if(Modernizr.mq('screen and (max-width:767px)')) {
                     $("#mydiv").appendTo("#block1");
        }
 
        else if(Modernizr.mq('screen and (min-width:768px)')) {
                                  $("#mydiv").appendTo("#block2");<span class="Apple-tab-span" style="white-space: pre;"> </span>
        }
 
    }
 
    var id;
    $(window).resize(function() {
        clearTimeout(id);
        id = setTimeout(doneResizing, 0);
    });
 
    doneResizing();
})(jQuery);
 

that's all

Wednesday, June 18, 2014

joomla back office Failed to parse time string (jerror) at position ....

hello moto;
Pre conditions: Joomla 3.0
i've encountred this error when migrating website from a server to another...
front office worked correctly
back office  no
Try to change $log_path et $tmp_path in configuration.php file
To know the correct directory
create a php file simple.php
<?php
echo getcwd (  );
?>
copy it at the root of the site
invoke it from web browser
get your directory
copy it an d and add /logs for logs and tmp for tmp dir





Monday, May 19, 2014

Prestashop déclaration de variable globale de configuration (Module FB/Twitter pour prestashop)

Lors de la création d'un module spécifique sous presta, nous avons souvent besoin de stocker quelques variables dans la base de données du système.
Dans le cas ou la variable est simple et que l'utilisation d'un CRUD  n'est pas aussi nécessaire, l'utilisation d'une variable système peut suffire, on parle d'une variable de configuration.
Comment la créer ?
c'est simple le fait de mettre à jour une variable de configuration qui n'existe pas la crée et lui affecte la valeur indiquée.

Configuration::updateValue('MA_VARIABLE',"");
On met ça dans la fonction installe de notre module si vous voulez.

Comment la lire?
c'est simple aussi
Configuration::get("MA_VARIABLE") retourne la variable

Dans ce qui suit, j'ai crée un petit exemple qui illustre ce comportement:
Un module qui affiche' 2 icones (fb+twitter) dont les adresses sont configurables depuis le back-office



block-fbtwitter (lien de téléchargement)


screen shot

Sunday, March 23, 2014

Module JCounter, visits counter for joomla

Here is JCounter module, a visits counter for joomla 2.5/3.x.
You must unzip file first and install the two components (plugin then module) in order to use it.
Current version is 1.3


Why plugin ?
When webmaster decide to disable this module on some web pages for design reasons or other, plugin continue to increase visits number, everwhen  module is disabled on that page.


 Download link for joola 2.5 and joomla 3.x


Thanks for your suggestions

Module Evolution
April 2011 version 1.0 for joomla 1.5
March 2014  version 1.1 joomla 2.5/ 3.x + introduction of the plugin ( binaries of this version were removed from repository due to wrong binaries upload)
July 2014 version 1.2
September 2014 version 1.3 added parameters text before and after / display font digits

Tuesday, March 11, 2014

Merge Two prestashop web sites into one multi shop website (ps 1.5.x)

Let's start by pre-conditions
www1 and www2  are two websites using ps 1.5.x
=> then we have two domains (or domain and subdomain ), 2 databases and 2 prestashop working folders.

how merge ?

1- login on BO of www1
2- Activate multishop support (preferences-> generales) (may be translated) and register
3- Now may see a new menu item "multi-shop" in advanced parameters menu.

now ps is ready to work on multishop  mode

4- copy the theme of www2 in the themes directory of www1
    => if the theme of www2 (the second web site) has the same name as the first one, you must change its name then (let say 'theme2')

5- Now enter the menu item multi-shop (step 3)

you will see at the left a tree but with only one item (the name of www1)

6- Click add a shop
  i- enter the name of your site (www2)
  ii- let the two combos as they are
  iii- choose the theme (step 4 normally)
   you may then choose a least one category (default) from the tree of categories
 iv- import data ? no
Register.

Now we have to link our shop to its  url
7- Click add link
 enter web site surl of site www2 (exp: www.mysite2.com) in both http and ssl modes
Register

8- Don't forget to activate url rewriting !
(preferences -> SEO and URLs )

Great now it will not work surely :)



9- What's the problem ?
We are searching to merge data and files => one BO (back office) and one global folder containing the two sites.
Solution:
In Cpanel /plesk/etc ....
www1 -> xxx/public_html/www1
www2-> xxx/public_html/www1










Saturday, February 15, 2014

Prestashop The database selection cannot be made.

when migrating prestahsop from one web site to other 'The database selection cannot be made.' error happened... although my user had ALL PRIVILEGES 
privs ...
granting explicit privilerges to my user (select , insert, duplicate etc ...) solved the problem.

grant select on ON db_ps.* TO 'your_user'@'host';
grant insert on ON db_ps.* TO 'your_user'@'host';
grant delete on ON db_ps.* TO 'your_user'@host';
grant update on ON db_ps.* TO 'your_user'@'host';

or simply

grant SELECT,INSERT,UPDATE,DELETE ON `db_ps`.* TO 'your_user'@'host';

MySQL doc here

Wednesday, January 8, 2014

Prestashop create admin controller with back office overload

this post talk about the implementation of admin controller in prestashop and tpl file, in cases we are not using standard CRUD operations on database tables via dao models(see ObjectModel mother class)
if your are interested by the standard way (in major cases, this article can help you)
http://doc.prestashop.com/display/PS15/Using+helpers+to+overload+a+back-office+template
if your template does not meet with usual templates (list, form, toolbar ....)
you can :

1- create your tpl file
2- put it in admin/themes/the_theme/template

3- set the template at the constructor by wrting:

    public function __construct() {
        parent::__construct();
        $this->template = 'your____tpl.tpl';
    }
you can see the source of adminController
http://searchcode.com/codesearch/view/50600141
it may be helpful