ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Business Logic, Part 2
Pages: 1, 2, 3

Additionally, you'll notice that this new manager has a method to update a user's password, setPassword( ). This makes perfect sense; however, no such method exists on the LDAPManager component. You'll need to add this method into that class, as shown here:



public boolean updatePassword(String username, 
        String oldPassword, String newPassword) 
    throws UserNotFoundException {
        
    // Ensure this is a valid user, with 
	// a valid (old) password
    boolean isValidUser = isValidUser(username, 
	    oldPassword);
    if (!isValidUser) {
        return false;
    }
    
    try {
        // Get the user
        DirContext userContext = 
            (DirContext)context.lookup(getUserDN(username));
        
        ModificationItem[] mods = new ModificationItem[1];
 
        // Create new password attribute
        mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
            new BasicAttribute("userPassword", newPassword));
        
        // Replace old with new
        userContext.modifyAttributes("", mods);
        
        return true;
    } catch (NamingException e) {
        e.printStackTrace(  );
        return false;
    }
}

Why All the Back and Forth?

If you are following along with the code in this book, you may be wondering why I am doing a lot of "back and forth" with adding methods, changing home interfaces, updating existing methods, and so on. I certainly could have made any later changes to my own code appear in earlier chapters (through the magic of editing and book production). However, this book is about enterprise application programming, and the constant refining of code is very much a part of that process. In other words, I'm trying to give you at least a semi-realistic view of how real-life programming works. Of course, you can download completed code for all classes online at http://www.newInstance.com if you don't want to deal with these issues.

All that's left at this point is the session bean's implementation class. There is very little explanation needed for this class; if you followed along in Chapters and , you can quickly pick up the code shown in Example 8-6. In a nutshell, the component acts as a client to various entity beans and LDAP components, piecing together disparate functions into one logical method. You should examine the groupings used for each method, and see how the underlying data sources and data formats are harnessed into easy-to-use methods for manager clients.


Example 8-6: The UserManager Implementation Class

Also in this series:

Business Logic, Part 3
In Part 3 of our excerpt from Building Java Enterprise Applications (Vol. 1, Architecture), Brett McLaughlin addresses issues of statelessness and statefulness.

Business Logic, Part 1
In this excerpt from Chapter 8 of Building Java Enterprise Applications, Vol I: Architecture, Brett McLaughlin discusses the fašade pattern, in which you use session beans to access entity beans. This access method is used instead of allowing direct access to entity beans, and is key to a sound strategy in building enterprise applications.

package com.forethought.ejb.user;
 
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
import com.forethought.ejb.util.SessionAdapter;
 
// Office bean
import com.forethought.ejb.office.OfficeInfo;
 
// UserType bean
import com.forethought.ejb.userType.UnknownUserTypeException;
 
// LDAPManager component
import com.forethought.ldap.LDAPManager;
import com.forethought.ldap.UserNotFoundException;
 
public class UserManagerBean extends SessionAdapter {
    
    /** <p> Required method for allowing bean lookups. </p> */
    public void ejbCreate(  ) throws CreateException {
        // No action required for stateless session beans
    }
 
    public UserInfo get(String username) throws RemoteException {
        User user = getUser(username);
        if (user != null) {
            return user.getInfo(  );
        } else {
            return null;
        }
    }
 
    public UserInfo add(String username, String password, 
                        String firstName, String lastName, 
                        String userType)
        throws RemoteException, UnknownUserTypeException {
         
        // Simply delegate, without an office
        return add(username, password, firstName, lastName, userType, null);
    }
 
    public UserInfo add(String username, String password, 
                        String firstName, String lastName, 
                        String userType, OfficeInfo officeInfo)
        throws RemoteException, UnknownUserTypeException {
         
        boolean addedToDirectory = false;
        LDAPManager manager = null;
        try {
            // Add user to directory server
            manager = getLDAPManager(  );
            manager.addUser(username, firstName, lastName, password);
            addedToDirectory = true;
 
            // Get an InitialContext
            Context context = new InitialContext(  );
 
            // Add user to database
            UserHome userHome = (UserHome) 
                context.lookup("java:comp/env/ejb/UserHome");
            User user = userHome.create(LDAPManager.getUserDN(username),
                                        userType, firstName, lastName,
                                        officeInfo);
            
            return user.getInfo(  );
        } catch (NamingException e) {
            /*
             * If added to directory, but not to database, remove back from
             * directory server
             */
            if (addedToDirectory) {
                try {
                    manager.deleteUser(username);
                } catch (Exception ignored) {
                    // If this dies, we're done
                }
            }
        } catch (CreateException e) {
            if (addedToDirectory) {
                try {
                    manager.deleteUser(username);
                } catch (Exception ignored) {
                    // If this dies, we're done
                }
            }
        }
        
        // If we got here, things failed
        return null;
    }
 
    public void update(UserInfo userInfo)
        throws RemoteException, UnknownUserTypeException {
        
        // This only involves database fields, so no LDAP access needed
        User user = getUser(userInfo.getId(  ));
        user.setInfo(userInfo);
    }
 
    public boolean setPassword(String username, String oldPassword, 
                               String newPassword)
        throws UserNotFoundException {
            
        try {
            LDAPManager manager = getLDAPManager(  );
            return manager.updatePassword(username, oldPassword, newPassword);
        } catch (NamingException e) {
            return false;
        }
    }
 
    public boolean authenticate(String username, String password)
        throws UserNotFoundException {
            
        try {
            return getLDAPManager(  ).isValidUser(username, password);
        } catch (NamingException e) {
            return false;
        }
    }
 
    public boolean delete(String username){
        User user = getUser(username);
        return delete(user);
    }
 
    public boolean delete(UserInfo userInfo) {
        User user = getUser(userInfo.getId(  ));
        return delete(user);
    }
    
    private User getUser(int id) {
        try {
            // Get an InitialContext
            Context context = new InitialContext(  );
 
            // Look up the User bean
            UserHome userHome = (UserHome) 
                context.lookup("java:comp/env/ejb/UserHome");
            User user = userHome.findByPrimaryKey(new Integer(id));
            
            return user;
        } catch (Exception e) {
            // Any problems - just return null
            return null;
        }
    }
 
    private User getUser(String username) {
        try {
            // Get an InitialContext
            Context context = new InitialContext(  );
 
            // Look up the User bean
            UserHome userHome = (UserHome) 
                context.lookup("java:comp/env/ejb/UserHome");
            User user = userHome.findByUserDn(LDAPManager.getUserDN(username));
            
            return user;
        } catch (Exception e) {
            // Any problems - just return null
            return null;
        }
    }
 
    private boolean delete(User user) {
        if (user == null) {
            return true;
        }
        try {
            user.remove(  );
            return true;
        } catch (Exception e) {
            // Any problems - return false
            return false;
        }
    }
    
    private LDAPManager getLDAPManager(  ) throws NamingException {
        /**
         * This could be set up to read from a properties file, but I have
         * kept it simple for example purposes.
         */
        LDAPManager manager = 
            LDAPManager.getInstance("localhost", 389,
                                    "cn=Directory Manager",
                                    "forethought");
        return manager;
    }
}

Almost all of the code shown is fairly straightforward: simple JNDI lookups for entity beans and operations upon those beans make up most of the class. Use of the LDAPManager component makes up almost all of the rest of the code. As you can see, the process of using two (or more) data sources, formats, or types is all abstracted nicely in the UserManager bean, and allows the client to happily add, delete, and update users without worrying about physical data storage details.

In the next article in this series, Brett covers State Design.

Brett McLaughlin had developed enterprise Java applications for Nextel Communications and Allegiance Telecom. When that became fairly mundane, Brett took on application servers. He then got hooked on open source software, and helped found several cool programming tools, like Jakarta turbine and JDOM.


View catalog information for Building Java Enterprise Applications Vol I: Architecture

Return to ONJava.com.