/*
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();
}
}