Parancoe
The easy-to-use web framework

Chapter 3. Parancoe Plugins

3.1. Introduction

Parancoe provide a plugin system for easily add features to your application. A Parancoe plugin is a JAR containing classes, the plugin configuration and the plugin definition. For adding a plugin to your Parancoe application, you simply have to put its JAR in your application classpath, or, if you are using Maven, to add the plugin in your application dependencies. The plugin will be automatically discovered, and its features will be ready to be used in your application.

At present the following plugins are available.

  • DWR
  • Italy
  • Security Encrypted
  • Spring Security
  • World

3.1. DWR

This plugin provides an easy integration of the Direct Web Remoting (DWR) framework, version 3. DWR is a framework for easily implement AJAX functionalities in a Java application.

3.1.1. How to add the plugin to your application

For adding the DWR plugin to your application, if your are using Maven, simply add the plugin dependency to your pom.xml

Example 3.1. DWR plugin dependency

<dependency>
    <groupId>org.parancoe</groupId>
    <artifactId>parancoe-plugin-dwr</artifactId>
    <version>2.0.2</version>
</dependency>

The DWR controller is mapped on the /dwr/* URLs. So add that URL pattern to the mapping of the parancoe servlet in your deployment descriptor ($PRJ/src/main/webapp/WEB-INF/web.xml):

    <servlet-mapping>
        <servlet-name>parancoe</servlet-name>
        <url-pattern>/dwr/*</url-pattern>
    </servlet-mapping>
    

For testing if the plugin is correctly installed, build and deploy you application, and point your browser to the <base_address>/dwr/index.html address (your base address will be something similar to http://localhost:8080/myapp). You should see the following page:

The empty DWR Test Page

Figure 3.1. The empty DWR Test Page


Of course, just after the installation you'll have no classes known to DWR.

3.1.2. A simple example

As a simple example we will implement a search page for searching the users of your application. The page will contain a single text field for typing the partial username to search. Every second, if the content of the text field has changed, an AJAX call will search the user database, and will build a list of the results in the page (of course without the need of a full refresh of the page).

Let's start writing the Java server-side code that will produce the results:

Example 3.2. UserSearch.java

package com.mycompany.testapp.ajax;

import java.util.List;
import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;
import org.parancoe.plugins.security.User;
import org.parancoe.plugins.security.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@RemoteProxy(name = "userSearch")
public class UserSearch {

    @Autowired
    private UserDao userDao;

    @RemoteMethod
    public String[] search(String partialUsername) {
        List<User> users =
                userDao.findByPartialUsername(partialUsername);
        String[] usernames = new String[users.size()];
        int i = 0;
        for (User user : users) {
            usernames[i++] = user.getUsername();
        }
        return usernames;
    }
}
        

Add the scanning of the package of this class in your parancoe-servlet.xml file, if it's not already included:

<context:component-scan base-package="com.mycompany.testapp.ajax"/>
The not empty DWR Test Page

Figure 3.2. The not empty DWR Test Page


You can try to ajax-call your method in the class test page:

The UserSearch DWR Test Page

Figure 3.3. The UserSearch DWR Test Page


Now you can use that call in your pages. For example, add the $PRJ/src/main/webapp/userSearch.jsp page:

Example 3.3. userSearch.jsp

<%@ include file="WEB-INF/jsp/common.jspf" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <%@ include file="WEB-INF/jsp/head.jspf" %>
        <script src="${cp}/dwr/interface/userSearch.js" type="text/javascript"></script>
        <script src="${cp}/dwr/engine.js" type="text/javascript" ></script>
        <script src="${cp}/dwr/util.js" type="text/javascript"></script>
    </head>
    <body>
        <h1>Search Users</h1>
        
        <div>                    
            <form id="userSearchForm" action="" method="get">
                <label>Username:</label><input id="username" name="username" type="text"/>
            </form>
        </div>
        
        <div style="clear: both;"><ul id ="userSearch_result"></ul></div>
        
        <script type="text/javascript">
            new Form.Observer('userSearchForm', 1, function(el, value) {
                var formValues = value.parseQuery();
                userSearch.search(formValues.username, function(users) {
                    $('userSearch_result').update('');
                    users.each(function(user) {
                        $('userSearch_result').insert('<li>'+user+'</li>');
                    });
                });
            });
        </script>                    
    </body>
</html>

Pointing you browser to that page you'll see the desired result:

The userSearch.jsp page in action

Figure 3.4. The userSearch.jsp page in action


Using directly the collection of objects, in place of array of strings, make the code even simpler.

Example 3.4. UserSearch.java returning a list of User objects

package com.mycompany.testapp.ajax;

import java.util.List;
import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;
import org.parancoe.plugins.security.User;
import org.parancoe.plugins.security.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@RemoteProxy(name = "userSearch")
public class UserSearch {

    @Autowired
    private UserDao userDao;

    @RemoteMethod
    public List<User> search(String partialUsername) {
        return userDao.findByPartialUsername(partialUsername);
    }
}

The code in the JSP doesn't almost change. Update just the single line where you expose the data in the page, accessing the username attribute of the JavaScript object:

$('userSearch_result').insert('<li>'+user.username+'</li>');

Finally, for passing User objects, you need to declare it in your DWR configuration in your parancoe-servlet.xml file:

<dwr:configuration>
    <dwr:convert type="bean" class="org.parancoe.plugins.security.User" />
    <dwr:convert type="bean" class="org.parancoe.plugins.security.Authority" />
</dwr:configuration>

When you'll put the application in production, probably you'll want the DWR Test Page being accessible no more. For disabling it, override the DWR controller in your parancoe-servlet.xml, setting the debug attribute to false:

<dwr:controller id="dwrController" debug="false">

3.2. Italy

This plugin provides the data of the italian regions, provinces and municipalities.

3.2.1. How to add the plugin to your application

For adding the Italy plugin to your application, if your are using Maven, simply add the plugin dependency to your pom.xml

Example 3.5. Italy plugin dependency

<dependency>
    <groupId>org.parancoe</groupId>
    <artifactId>parancoe-plugin-italy</artifactId>
    <version>2.0.1</version>
</dependency>
            

3.2.2. A simple example

The plugin provides persistent classes and a DAOs for accessing the italian data. For example, for retrieving the list of all italian regions:

Example 3.6. A class using the RegioneDao

package com.mycompany.testapp.blo;

import java.util.List;
import javax.annotation.Resource;
import org.parancoe.plugins.italy.Regione;
import org.parancoe.plugins.italy.RegioneDao;
import org.springframework.stereotype.Component;

@Component
public class RegionalBusiness {

    @Resource
    private RegioneDao regioneDao;

    public List<Regione> retriveAllRegions() {
        return regioneDao.findAll();
    }
}
            

For checking if the plugin is working, you can write a simple test of the previous class:

Example 3.7. A test for the class of the example

package com.mycompany.testapp.blo;

import java.util.List;
import org.parancoe.plugins.italy.Comune;
import org.parancoe.plugins.italy.Procura;
import org.parancoe.plugins.italy.Provincia;
import org.parancoe.plugins.italy.Regione;
import org.parancoe.web.test.BaseTest;
import org.springframework.beans.factory.annotation.Autowired;

public class RegionalBusinessTest extends BaseTest {

    @Autowired
    private RegionalBusiness regionalBusiness;

    public void testRetriveAllRegions() {
        List<Regione> result = regionalBusiness.retriveAllRegions();
        assertSize(20, result);
    }

    @Override
    public Class[] getFixtureClasses() {
        return new Class[]{Regione.class, Provincia.class, Comune.class,
                    Procura.class
                };
    }
}
            

3.1. Security Encrypted

TBW

3.2. Spring Security

TBW

3.3. World

TBW