Sun GlassFish Mobility Platform 1.1 Developer's Guide for Enterprise Connectors

Example: The MusicAlbumsResource Container Class

In the MusicDB example, the MusicAlbumsResource class is the container class. After importing needed packages, the resource class begins with a @Path annotation that establishes the URLs:

@Path("albums")
public class MusicAlbumsResource {

The HTTP operations will use the URLs http://server:port/context-root/resources/albums and http://server:port/context-root/resources/albums/{id}. For example, if you specify musicdb-ws as the context root and are running the Enterprise Server on your own system, the URL for retrieving the business objects would be http://localhost:8080/musicdb-ws/resources/albums.

The next few lines define the file extension to be used for these business objects, a JAX-RS context, and a class constructor. They also define a user name prefix specific to this Enterprise Connector, to be used by the lifeCycle method:

    private static final String EXTENSION = ".alb";
    private static final String DB_USER_NAME = "musicdbuser";
    
    @Context
    private UriInfo context;
    
    public MusicAlbumsResource() {
    }

Next, the lifeCycle method provides code to establish or terminate a connection to the database, using the ConnectionPool defined in src/main/java/com/sun/mep/ws/musicdb/util/ConnectionPool.java. Both the createConnection and destroyConnection methods take a session ID argument.

    @POST
    @Produces("text/plain")
    public String lifeCycle(
            @QueryParam("username") @DefaultValue("username") String user,
            @QueryParam("password") @DefaultValue("password") String password,
            @QueryParam("sessionId") @DefaultValue("") String sessionId,
            @QueryParam("operation") String operation) 
    {
        if (operation.equals("initialize")) {
            if (!user.startsWith(DB_USER_NAME)) {
                throw new RuntimeException("A MusicDB user name must start " 
                        + "with the '"+ DB_USER_NAME + "' prefix");
            }
            ConnectionPool.getInstance().createConnection(sessionId);
        }
        else if (operation.equals("terminate")) {
            ConnectionPool.getInstance().destroyConnection(sessionId);
        }
        else {
            throw new RuntimeException("Lifecycle operation " + operation + 
                    " not understood");
        }
        return EXTENSION;
    }

For the MusicDB application, a connection can be established only if the user name begins with musicdbuser. At the end, the method returns the string .alb, the file extension for music albums.

The getBusinessObjects method begins by using another connection to create a JDBC statement:

    @GET
    @Produces("text/xml")
    public BusinessObjects getBusinessObjects(
            @QueryParam("username") @DefaultValue("username") String user,
            @QueryParam("password") @DefaultValue("password") String password,
            @QueryParam("sessionId") @DefaultValue("") String sessionId,
            @QueryParam("useTimestamps") @DefaultValue("false") boolean useTimestamps)
    {
        Statement stmt = null;
        
        try {
            // Create SQL statement from connection
            ConnectionPool pool = ConnectionPool.getInstance();
            stmt = pool.getConnection(sessionId).createStatement();

The useTimestamps argument of the method, which is specific to the MusicDB Enterprise Connector, provides the value of the useTimestamps flag. An administrator can set the value of the useTimestamps property when defining the Enterprise Connector in the Sun GlassFish Mobility Platform Administration Console. If the property is not set, the argument value is set to false.

It then executes the template code that instantiates the list of JAXB objects:

            // Get list of business objects to return
            BusinessObjects result = new BusinessObjects();
            List<BusinessObject> resultList = result.getBusinessObject();

Next, the method performs an SQL query to retrieve from the back-end database all the business objects that belong to the user who is logged in to the Enterprise Connector:

            ResultSet rs = stmt.executeQuery(
                    "SELECT * FROM album WHERE username = '" + user + "'");

The method iterates through the query result set, instantiating each business object (in this case, a MusicAlbum) and populating it with its retrieved properties (including the lastModified property if the useTimestamps flag is set), then serializing it to a JAXB object and adding it to the list of objects. Finally, the method closes the result set and returns the list of JAXB objects.

            while (rs.next()) {
                // Use temporary object for serialization purposes
                MusicAlbum album = new MusicAlbum(user, false);
                album.setName(rs.getString(1));
                album.setArtist(rs.getString(2));
                album.setDatePublished(rs.getString(3).replace("-", ""));
                album.setRating(rs.getInt(4));
                if (useTimestamps) {
                    album.setLastModified(rs.getTimestamp(6).getTime());
                }
                
                // Map MusicAlbum to JAXB bean
                BusinessObject bo = new BusinessObject();
                bo.setName(album.getName());
                bo.setValue(album.serialize());
                if (useTimestamps) {
                    bo.setLastModified(album.getLastModified());
                }
                
                // Add BusinessObject to result list
                resultList.add(bo);
            }
            rs.close();  
            
            return result;
        }
        catch (Exception e) {
            throw new RuntimeException(e); 
        }
        finally {
            if (stmt != null) {
                try { stmt.close(); } catch (Exception e) { /* ignore !*/ }
            }
        }        
    }