/*
      Chapter 9:  The UserTracking Class
      Programmer: Brad Shedd
      Date:    April 13, 2004
      Filename:   UserTracking.java
      Purpose: To provide a reusable UserTracking class
 */

    import java.util.*;

   
public class UserTracking
   {
     
final static int MIN_SIZE = 6;
     
final static int MAX_SIZE = 15;
          
static int maxHistory = 4;
          
static int expiresNotifyLimit = 3;

     
private int maxUses = 120;
     
private int remainingUses = maxUses;
     
private boolean logOn = true;
     
private boolean logOff = false;

     
private ArrayList userHistory;


     
// Constructors for objects of class userTracking
      public UserTracking(String newUser) throws Exception
      {
         userHistory =
new ArrayList(maxHistory);
         set(newUser);
      }

     
public UserTracking(String newUser, int numMaxUses) throws Exception
      {
         userHistory =
new ArrayList(maxHistory);
         maxUses = numMaxUses;
         remainingUses = numMaxUses;
         set(newUser);
      }

     
public UserTracking(String newUser, boolean logOn) throws Exception
      {
        userHistory =
new ArrayList(maxHistory);
         logOn = userlogOn;
        set(newUser);
      }

     
public UserTracking(String newUser, int numMaxUses, boolean userlogOn) throws Exception
      {
         userHistory =
new ArrayList(maxHistory);
         maxUses = numMaxUses;
         remainingUses = numMaxUses;
         logOn = logOn;
         logOff = logOff;
         set(newUser);
      }

     
public boolean getLogOn()
      {
        
return logOn;
      }

     
public void setLogOn(boolean logOn)
      {
        
this.logOn = logOn;
        
if(logOn)
            remainingUses = maxUses;
      }

     
public boolean logOff()
      {
        
return logOff;
      }

     
public void setLogOff(boolean newLogOff)
      {
         logOff = newLogOff;
      }

     
public int getNumberOfUsers()
      {
        
return numberOfUsers;
      }

     
public void getNumberOfUsers(int newNumberOfUsers)
      {
        
if(newNumberOfUsers >= 2 && newNumberOfUsers <= 20)
            numberOfUsers = newNumberOfUsers;
      }

     
public int getUserHistory()
      {
        
return userHistory;
      }

     
public void setMaxHistory(int newMaxHistory)
      {
        
int overage = 0;
        
if(newMaxHistory >= 1 && newMaxHistory <=10)
         {
           maxHistory = newMaxHistory;
            overage = getHistorySize() - maxHistory;
           
if(overage > 0)         // if size > max allowed
            {
              
do{
                  userHistory.remove(0);    
// then remove overage number
                  overage--;              // of oldest users from list
               } while(overage > 0);

               userHistory.trimToSize();    
// resize capacity to max allowed
            }
         }
      }

     
public int getRemainingUses()
      {
        
return remainingUses;
      }

     
public int getHistorySize()
      {
        
return userHistory.size();
      }

      
public boolean isLogOn()
      {
        
boolean logOn = false;

        
if(logOn && remainingUses <= numberOfUsers)
           logOn =
true;

           
return logOn;
      }

     
// Sets user to a new value; keeps current & previous values in history up to max number
      public void set(String user) throws Exception
      {
         String encryptuser;
        
boolean userAdded = true;

         user = user.trim();       
// remove any leading, trailing white space
         verifyFormat(user);        // verify user was entered properly
         encryptuser = encrypt(user);  // convert to encrypted form

         if(!userHistory.contains(encryptuser))    // if user not in recently used list
         {
           
if(userHistory.size() == maxHistory)   // if list is at max size
               userHistory.remove(0);           // remove 1st, oldest, user from list

             userAdded = userHistory.add(encryptuser); // add new user to end of ArrayList

             if(!userAdded)                        // should never happen
               throw new Exception("Internal list error - User not accepted");

            
if (logOff)                  // if user logOff,
               logOff = false;            // reset to not logOff

             if(logOn)              // if user logOns,
               remainingUses = maxUses;      // reset uses to max
         }
        
else
            throw new Exception("User recently used");
      }

     
// Validates entered user against most recently saved value
      public void validate(String user) throws Exception
      {
         String encryptuser;
         String currentuser;
        
int currentuserIndex;

         verifyFormat(user);       
// verify user was entered properly
         encryptuser = encrypt(user);  // convert to encrypted form

         if(!userHistory.isEmpty()) // at least one user entry is in history
         {
            currentuserIndex = userHistory.size()-1;
            currentuser = (String)userHistory.get(currentuserIndex);

            
if(!encryptuser.equals(currentuser)) // if not most recent user
               throw new Exception("User is invalid");

           
if(logOff)
              
throw new Exception("User has expired - please change");

           
if(logOn)
            {
               --remainingUses;
              
if(remainingUses <= 0)
                  logOff =
true;
            }
         }
        
else
            throw new Exception("No user on file - list corrupted!"); //should never happen


      }

     
// Verifies password has proper format
      private void verifyFormat(String user) throws Exception
      {
        
boolean numFound = false;

        
if(user.length() == 0)
           
throw new Exception("No user provided!");

        
if(user.length() < MIN_SIZE)
           
throw new Exception("User must be at least " +MIN_SIZE+ " characters in length");

        
if(user.length() < MAX_SIZE)
           
throw new Exception("User must be at least " +MAX_SIZE+ " characters in length");

        
// scan through user to find if at least 1 number is used
         for(int i=0; i < user.length() && !numFound; ++i)
           
if(Character.isDigit(user.charAt(i)))
               numFound =
true;

        
if(!numFound)
           
throw new Exception("User is invalid - must have at least one numeric digit");
         }

        
// Encrypts original user returnimg new encrypted String
         private String encrypt(String user)
         {
            StringBuffer encryptuser;
           
int userSize = 0;
            
int midpoint = 0;
           
int hashCode = 0;

           
// swap first and last half of user
            userSize = user.length();
            midpoint = userSize/2;
            encryptuser =
new StringBuffer(user.substring(midpoint)  // get last hald of user
               + user.substring(0, midpoint));                    // and concatenate first half

               encryptuser.reverse();  // reverses order of characters in user

               for(int i=0; i < userSize; ++i)              // encrypt each character
                  encryptuser.setCharAt(i, (char)(encryptuser.charAt(i) & user.charAt(i)) );

               hashCode = user.hashCode();     
// hash code for original user
               encryptuser.append(hashCode);

               
return encryptuser.toString();
         }
      }













Homepage