ref: 48e2e0e38472ce670c97a2e0bcbebcaca2572823
dir: /Main.java/
//package BookProj;
// XXX get rid of *s
// handle throws
/*
import java.util.regex.Pattern; // Pattern, Matcher
import java.util.Matcher; // Scanner, ArrayList
import java.util.Scanner;
*/
import java.util.*;
import java.time.LocalDateTime;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.io.Console;
import java.io.File;
enum Role
{
Admin,
User;
}
enum BookAttr
{
ISBN,
Status,
AgeGroup,
Abstract,
Author,
Name,
Owner;
}
enum UserAttr
{
Username,
role,
Reserved,
ID,
RegTime,
Age;
}
enum AdminAttr
{
Username,
role,
Reserved,
ID,
RegTime,
Password,
Active;
}
interface Library
{
/* admin */
boolean Login(Admin a, String pass);
void Logout(Admin a);
Admin NewAdmin(String user, String pass);
void DelAdmin(Admin a);
boolean CheckAdmin(String a);
Admin MatchAdmin(String un);
boolean FindAdmin(AdminAttr k, Pattern q);
/* user */
boolean Login(User u);
// void Logout(User u);
// User NewUser();
// void DelUser(User u);
boolean CheckUser(String u);
User MatchUser(String un);
boolean FindUser(UserAttr k, Pattern q);
/* books */
void TakeBook(String un, String isbn);
void TakeBook(Admin u, Book b);
void TakeBook(User u, Book b);
void ReturnBook(User u);
void ReturnBook(Admin u);
Book NewBook(String isbn, String name, String author, String abst, int agegroup);
void DelBook(Book b);
boolean CheckBook(String ISBN);
Book MatchBook(String isbn);
boolean FindBook(BookAttr k, Pattern q);
/*
String FindBook(String ISBN, String value); // Pointer to ISBN
void ReturnBook(String ISBN);
void ReturnBook(Book b);
boolean WriteStatus();
boolean FindBook(boolean q); for Status value searchs
*/
interface UI
{
void Program();
void LoginMenu();
/* checks password with user, gets input from GetPassword */
boolean AskPass(Admin u);
boolean AskPass(User u);
/* different Menus, for different Users to handle */
void Menu(Admin u);
void Menu(User u);
/* Gets a String, either console or scanner, just check if it's valid or not */
String GetUsername();
String GetPassword();
/* asks for user/book info, returns username/isbn if it exists */
String AskAdmin();
String AskUser();
String AskBook();
/* search foolan menu */
void SearchAdmin();
void SearchUser();
void SearchBook();
/* add foolan menu */
void AddAdmin();
void AddUser();
void AddBook();
/* remove foolan menu */
void RemAdmin();
void RemUser();
void RemBook(); // maybe it's stolen
/* list foolan menu */
void ListAdmin();
void ListUser();
void ListBook();
}
}
/* i personally don't use it
but here is a converter */
class Books
{
HashMap<BookAttr, String> Book = new HashMap<BookAttr, String>();
HashMap<String, HashMap> Booklist = new HashMap<String, HashMap>();
HashMap<String, HashMap> Mkbl(HashMap<String, Book> bl)
{
HashMap<String, HashMap> list = new HashMap<String, HashMap>();
for(Book i: bl.values())
{
list.put(i.getISBN(), i.toHashMap());
}
return list;
}
}
class Book
{
/* book is untaken by default */
private boolean Status = false;
private String Abstract, Author, Name, ISBN;
private String Owner = ""; /* Username of user who reserved it */
private int ageGroup;
/* should a register be a constractor? XXX
should it even named register? */
Book(String name, String author, String abs, String i, int age)
{
/* joy of joys willy */
this.Abstract = abs;
this.Author = author;
this.Name = name;
this.ISBN = i;
this.ageGroup = age;
}
boolean AgeOk(int age)
{
if(this.ageGroup <= age)
return true;
else
return false;
}
boolean setOwner(String u)
{
if(!this.Owner.isEmpty())
{
System.err.println("A User (ID:" + this.getOwner() + ") already got the book");
return false;
}
this.Owner = u;
return true;
}
boolean setStatus(boolean b)
{
if(this.Status == b)
{
System.err.println("book (ISBN: " + this.getISBN() + ") status already set to: " + this.Status);
return false;
}
this.Status = b;
return true;
}
boolean getStatus()
{
return Status;
}
String getAbstract()
{
return this.Abstract;
}
String getAuthor()
{
return this.Author;
}
String getName()
{
return this.Name;
}
String getISBN()
{
return this.ISBN;
}
int getAgeGroup()
{
return this.ageGroup;
}
String getOwner()
{
return this.Owner;
}
HashMap<BookAttr, String> toHashMap()
{
HashMap<BookAttr, String> temp = new HashMap<BookAttr, String>();
temp.put(BookAttr.ISBN, this.ISBN);
temp.put(BookAttr.Status, Boolean.toString(this.Status));
temp.put(BookAttr.AgeGroup, Integer.toString(this.ageGroup));
temp.put(BookAttr.Name, this.Name);
temp.put(BookAttr.Author, this.Author);
temp.put(BookAttr.Abstract, this.Abstract);
return temp;
}
}
abstract class BasicUser
{
private Role role;
private String Username, Reserved;
private int ID;
private LocalDateTime RegTime;
public boolean Active = false;
// abstract boolean IsReserved(String ISBN);
BasicUser(Role r, String u, int id, LocalDateTime rt)
{
this.role = r;
this.Username = u;
this.ID = id;
this.RegTime = rt;
}
Role getRole()
{
return this.role;
}
String getUsername()
{
return this.Username;
}
int getID()
{
return this.ID;
}
boolean setReserved(String ISBN)
{
/* ensure he has no books */
if(this.Reserved == null)
{
/* ensure book is not taken by someone else
if(
return true; */
return true;
}
else
{
System.err.println("the user already have a book");
return false;
}
}
boolean hasReserved()
{
if(this.Reserved.isEmpty())
return false;
else
return true;
}
String getReserved()
{
return this.Reserved;
}
LocalDateTime getRegTime()
{
return this.RegTime;
}
}
class Admin extends BasicUser
{
private String Password;
Admin(String user)
{
super(Role.Admin, user, (int)(Math.random()*100), LocalDateTime.now());
}
Admin(String user, String Pass)
{
/* maybe check if password is too easy? */
super(Role.Admin, user, (int)(Math.random()*100), LocalDateTime.now());
this.setPassword(Pass);
}
boolean setReserved(String ISBN)
{
return false; /* XXX */
}
boolean isReserved(String ISBN)
{
return false; /* XXX */
}
boolean checkPass(String pass)
{
if(this.Password.equals(pass))
return true;
else
return false;
}
void setPassword(String pass)
{
this.Password = pass;
}
}
class User extends BasicUser
{
private int Age;
User(String username, int age)
{
super(Role.User, username, (int)(Math.random()*1000+101), LocalDateTime.now());
this.Age = age;
}
boolean IsReserved(Book b)
{
if(this.getReserved().equals(b.getISBN()))
return true;
else
return false;
}
boolean IsReserved(String ISBN)
{
if(this.getReserved() == ISBN)
return true;
else
return false;
}
}
class Lib implements Library
{
/* Username, Admin/User, ISBN, Book */
private HashMap<String, Admin> AdminList = new HashMap<String, Admin>();
private HashMap<String, User> UserList = new HashMap<String, User>();
private HashMap<String, Book> BookList = new HashMap<String, Book>();
/*
private HashMap<String, HashMap> AdminList = new HashMap<String, HashMap>;
private HashMap<String, HashMap> UserList = new HashMap<String, HashMap>;
private HashMap<String, HashMap> BookList = new HashMap<String, HashMap>;
private HashMap<String, HashMap> = new HashMap<String, HashMap>;
*/
private ArrayList<Admin> AdminQuery = new ArrayList<Admin>();
private ArrayList<User> UserQuery = new ArrayList<User>();
private ArrayList<Book> BookQuery = new ArrayList<Book>();
static Admin adm;
static User usr;
int ResCount = 0;
/* is hasNextLine is of any of use? i wonder, says timmy */
public int readint(Scanner s, String errmsg, String inputmsg)
{
System.out.println(inputmsg);
while(!s.hasNextLine())
{
System.err.println(errmsg);
System.out.print(inputmsg);
s.nextLine();
}
return s.nextInt();
}
public String readstr(Scanner s, String errmsg, String inputmsg)
{
System.out.println(inputmsg);
while(!s.hasNextLine())
{
System.err.println(errmsg);
System.out.print(inputmsg);
s.nextLine();
}
return s.nextLine();
}
public boolean Login(Admin u, String pass)
{
/* clear null */
adm = null;
if(u.Active)
throw new IllegalStateException("Admin is already active?");
/* maybe later i want to do more stuff here */
if(u.checkPass(pass))
{
u.Active = true;
adm = u;
return true;
}
else
return false;
}
public void Logout(Admin u)
{
boolean b;
for(Admin i : this.AdminList.values())
{
if(i == u)
b = true;
}
if(!b)
throw new NoSuchElementException("No such Admin exists.");
u.Active = false;
}
public boolean Login(User u)
{
if(u.Active)
throw new IllegalStateException("Admin is already active?");
/* maybe later i want to do more stuff here */
u.Active = true;
}
public Admin NewAdmin(String user, String pass)
{
Admin a;
for(Admin i : this.AdminList.values())
{
if(i.getUsername().equals(user))
throw new IllegalArgumentException("Admin already exists");
}
/* if user is "admin", use defaults */
if(user.equals("admin"))
a = new Admin("admin", "pass");
else
a = new Admin(user, pass);
this.AdminList.put(a.getUsername(), a);
return a;
}
/* i could've made them overload,
however, this might led to unwanted results */
public void DelAdmin(Admin u)
{
if(!u.getReserved().isEmpty())
{
System.err.println("Admin " + u.getUsername() + " has a reserved book.");
return;
}
this.AdminList.remove(u.getUsername(), u);
}
public void DelUser(User u)
{
if(!u.getReserved().isEmpty())
{
System.err.println("User " + u.getUsername() + " has a reserved book.");
return;
}
this.UserList.remove(u.getUsername(), u);
}
/* should there be checks */
public Book NewBook(String isbn, String name, String author, String abst, int agegroup)
{
for(Book b : this.BookList.values())
{
if(b.getISBN().equals(isbn))
{
throw new IllegalStateException("Book already exist");
}
}
Book b = new Book(name, author, abst, isbn, agegroup);
this.BookList.put(isbn, b);
return b;
}
public void DelBook(Book b)
{
if(!b.getOwner().isEmpty())
{
// System.err.println("User " + b.getOwner() + " have reserved this book.");
throw new IllegalStateException("Book is reserved.");
}
this.BookList.remove(b.getISBN());
}
public boolean CheckBook(String isbn)
{
boolean b = false;
for(Book i : this.BookList.values())
{
if(i.getISBN().equals(isbn))
b = true;
}
if(!b)
{
System.err.println("No such user found, try again");
}
return b;
}
public Book MatchBook(String isbn)
{
Book b = null;
for(Book i : this.BookList.values())
{
if(i.getISBN().equals(isbn))
b = i;
}
if(b == null)
{
throw new NoSuchElementException("No such Admin exists.");
}
return b;
}
public boolean FindBook(BookAttr k, Pattern p)
{
/* flush last query */
this.BookQuery.clear();
Matcher m;
switch(k)
{
/* XXX should i use i.getFoolan.contains()? */
case AgeGroup:
for(Book i : BookList.values())
{
m = p.matcher(Integer.toString(i.getAgeGroup()));
if(m.find())
this.BookQuery.add(i);
}
break;
case Abstract:
for(Book i : BookList.values())
{
m = p.matcher(i.getAbstract());
if(m.find())
this.BookQuery.add(i);
}
break;
case Author:
for(Book i : BookList.values())
{
m = p.matcher(i.getAuthor());
if(m.find())
this.BookQuery.add(i);
}
break;
case Name:
for(Book i : BookList.values())
{
m = p.matcher(i.getName());
if(m.find())
this.BookQuery.add(i);
}
break;
case ISBN:
for(Book i : BookList.values())
{
m = p.matcher(i.getISBN());
if(m.find())
this.BookQuery.add(i);
}
break;
default:
// XXX write stuff and nag in case of invalid stuff
break;
}
if(this.BookQuery.size() == 0)
return false;
else
return true;
}
public boolean CheckAdmin(String a)
{
for(Admin i : this.AdminList.values())
{
if(i.getUsername().equals(a))
{
return true;
}
}
return false;
}
public Admin MatchAdmin(String un)
{
Admin a = null;
for(Admin i : this.AdminList.values())
{
if(i.getUsername().equals(un))
a = i;
}
if(a == null)
{
throw new NoSuchElementException("No such Admin exists.");
}
return a;
}
public boolean CheckUser(String u)
{
for(User i : this.UserList.values())
{
if(i.getUsername().equals(u))
{
return true;
}
}
return false;
}
public User MatchUser(String un)
{
User u = null;
for(User i : this.UserList.values())
{
if(i.getUsername().equals(un))
u = i;
}
if(u == null)
{
throw new NoSuchElementException("No such User exists.");
}
return u;
}
public boolean FindUser(UserAttr k, Pattern q)
{
}
public boolean FindBook(boolean q)
{
/* flush last query */
this.BookQuery.clear();
for(Book i : BookList.values())
{
if(i.getStatus())
this.BookQuery.add(i);
}
if(this.BookQuery.size() == 0)
return false;
else
return true;
}
/* user/admin's ID, ISBN */
public void TakeBook(String un, String isbn)
{
Book b = this.BookList.get(isbn);
if(this.CheckUser(un))
TakeBook(MatchUser(un), b);
else if(this.CheckAdmin(un))
TakeBook(MatchAdmin(un), b);
else
System.err.println("No such User or Admin " + un + " has found");
}
/* they shouldn't be able to get a book, but still */
public void TakeBook(Admin u, Book b)
{
/* check if book is taken */
if(b.getStatus())
{
System.err.println("Given book (ISBN: " + b.getISBN() + ") has been reserved.");
return;
}
/* he has some book? blasmphy! */
if(!u.getReserved().isEmpty())
{
System.err.println("User (ID: " + u.getUsername() +
") already has a book (" + u.getReserved() + ").");
return;
}
u.setReserved(b.getISBN());
b.setOwner(u.getUsername());
this.ResCount++;
}
public void TakeBook(User u, Book b)
{
/* check if book is taken */
if(b.getStatus())
{
System.err.println("Given book (ISBN: " + b.getISBN() + ") has been reserved.");
return;
}
/* he has some book? blasmphy! */
if(!u.getReserved().isEmpty())
{
System.err.println("User (ID: " + u.getID() + ") already has a book (" + u.getReserved() + ").");
return;
}
u.setReserved(b.getISBN());
b.setOwner(u.getUsername());
this.ResCount++;
}
public void ReturnBook(Admin u)
{
Book b = null;
if(u.getReserved().isEmpty())
{
System.err.println("Admin " + u.getUsername() + " has no book reserved");
return;
}
for(String i : this.BookList.keySet())
{
if(u.getReserved().equals(i))
{
b = this.BookList.get(i);
break;
}
}
if(b == null)
throw new NoSuchElementException("No such book exists.");
u.setReserved(null);
b.setOwner(null);
this.ResCount--;
}
public void ReturnBook(User u)
{
Book b = null;
if(u.getReserved().isEmpty())
{
System.err.println("User " + u.getUsername() + " has no book reserved");
return;
}
for(String i : this.BookList.keySet())
{
if(u.getReserved().equals(i))
{
b = this.BookList.get(i);
break;
}
}
if(b == null)
throw new NoSuchElementException("No such book exists.");
u.setReserved(null);
b.setOwner(null);
this.ResCount--;
}
class conUI implements UI
{
public void Program()
{
while(true)
{
/* there is no admin! */
if(AdminList.size() == 0)
{
AddAdmin();
adm.Active = true;
}
else
this.LoginMenu();
while(adm.Active || usr.Active)
{
/* only exits if user either logs out or smh */
this.Menu(adm);
/* user wants to quit */
if(adm.Active)
return;
}
}
}
public void LoginMenu()
{
Scanner s;
String un;
String pass;
System.out.println("Login> Username?> ");
un = s.nextLine();
if(CheckAdmin(un))
{
System.out.println("Login> Pass?> ");
pass = this.GetPassword();
Admin a = MatchAdmin(un);
if(Login(a, pass))
{
System.out.println("Auth as " + a.getUsername() + " sucessful");
return;
}
else
{
System.out.println("Auth fail");
return;
}
}
else if(CheckUser(un))
{
User u = MatchUser(un);
if(Login(u))
{
System.out.println("Login sucessful");
}
}
}
/* checks if password is valid, kinda like passwd */
public boolean Askpass(Admin u)
{
}
public void Menu(Admin a)
{
int in;
Scanner s = new Scanner(System.in);
System.out.println("Welcome, " + a.getUsername() + "!");
while(true)
{
System.out.print(
" 1) new book\n" +
" 2) new user\n" +
" 3) find book\n" +
" 4) take book\n" +
" 5) return book\n" +
" 6) logout\n" +
" 7) quit!\n" +
" 8) add new admin\n" +
" 9) delete admin\n" +
"10) list admins\n" +
"11) list books\n");
System.out.print("menu> ");
while(!s.hasNextInt())
{
System.err.println("Please enter a valid input");
System.out.print("menu> ");
s.nextLine();
}
in = s.nextInt();
switch(in)
{
case 1:
this.AddBook();
break;
case 2:
//this.AddUserr();
System.err.println("XXX todo");
break;
case 3:
this.SearchBook();
break;
case 4:
// this.TakeBook();
break;
case 5:
// this.ReturnBook();
break;
case 6:
System.out.println("Logging out...");
Logout(adm);
return;
case 7:
return;
case 8:
System.out.println("This action requires admin password");
if(this.Askpass(adm)) /* current admin */
this.AddAdmin();
else
System.err.println("Incorrect Password.");
break;
case 9:
System.out.println("This action requires admin password");
// if(this.Askpass(this.adm)) /* current admin */
// this.DelAdmin();
// else
// System.err.println("Incorrect Password.");
break;
case 10:
this.ListAdmin();
break;
case 11:
this.ListUser();
break;
case 12:
this.ListBook();
break;
default:
System.out.println("Invalid answer!, please try again.");
break;
}
}
}
public String GetUsername()
{
Scanner s;
String user;
do
{
System.out.println("Username?> ");
user = s.nextLine();
}while(user.contains(" "));
return user;
}
public String GetPassword()
{
String pass;
if(System.console() != null)
{
Console c;
do
{
pass = new String(c.readPassword("[%s]", "Password?>"));
}while(pass.contains(" "));
}
else
{
/* no console? */
Scanner s = new Scanner(System.in);
do
{
System.out.print("Password?> ");
pass = s.nextLine();
}while(pass.contains(" "));
}
return pass;
}
public void SearchBook()
{
String attr, patt;
Pattern pattern;
BookAttr ba;
Scanner s = new Scanner(System.in);
System.out.println("Attr: Status, Name, Abstract, ISBN, oISBN, AgeGroup etc.");
System.out.println("Find> What?> ");
attr = s.nextLine();
System.out.println("Find> Pattern?> ");
patt = s.nextLine();
pattern = Pattern.compile(patt, Pattern.CASE_INSENSITIVE);
if(attr.equalsIgnoreCase("Status"))
ba = BookAttr.Status;
else if(attr.equalsIgnoreCase("Name"))
ba = BookAttr.Name;
else if(attr.equalsIgnoreCase("Author"))
ba = BookAttr.Author;
else if(attr.equalsIgnoreCase("Abstract"))
ba = BookAttr.Abstract;
else if(attr.equalsIgnoreCase("ISBN"))
ba = BookAttr.ISBN;
// else if(attr.equalsIgnoreCase("oISBN"))
// FindBook(BookAttr., p);
else if(attr.equalsIgnoreCase("AgeGroup"))
ba = BookAttr.AgeGroup;
else
{
System.err.println("Invalid Attr");
return;
}
if(FindBook(ba, pattern))
{
// XXX add isRegistered()
System.out.println("ISBN | Name | Author | Age Group");
for(Book i : BookList.values())
{
System.out.println(i.getISBN() +
" | " + i.getName() +
" | " + i.getAuthor() +
" | " + i.getAgeGroup());
}
}
else
System.out.println("No match has found");
}
public void AddAdmin()
{
/* isn't java wonderful billy? */
String user, pass;
Scanner s = new Scanner(System.in);
System.out.println("Setting up Admin:");
System.out.print("Admin username?> ");
user = s.nextLine();
if(user.equals(""))
return;
do
{
System.out.print("Admin password?> ");
pass = s.nextLine();
}while(pass.equals(""));
NewAdmin(user, pass);
}
/* make checks better, reject empty input etc,
regex perhaps? */
public void AddBook()
{
String name, isbn, author, abs;
Scanner s = new Scanner(System.in);
int agegroup;
Book b;
System.out.println("Book> Name?> ");
name = s.nextLine();
if(name.equals("q"))
return;
System.out.println("Book> ISBN?> ");
isbn = s.nextLine();
if(isbn.equals("q"))
return;
System.out.println("Book> Author?> ");
author = s.nextLine();
if(author.equals("q"))
return;
// XXX on a related note, should i care about dealing with multiline stuff?
System.out.println("Book> Abstract?> ");
abs = s.nextLine();
if(abs.equals("q"))
return;
System.out.print("Book> Age Group?> ");
while(!s.hasNextInt())
{
System.out.println("Please enter a valid input");
System.out.print("Book> Age Group?> ");
s.nextLine();
}
agegroup = s.nextInt();
if(agegroup < -1)
return;
b = NewBook(name, author, abs, isbn, agegroup);
System.out.println(b);
return;
}
public void ListAdmin()
{
System.out.println("Username | ID | Active | RegTime");
for(Admin i : AdminList.values())
System.out.println(i.getUsername() +
" | " + i.getID() +
" | " + i.Active +
" | " + i.getRegTime());
}
public void ListUser()
{
System.out.println("Username | ID | Reserved ISBN");
for(User i : UserList.values())
System.out.println(i.getRole() +
" | " + i.getUsername() +
" | " + i.getID() +
" | " + i.getReserved());
}
public void ListBook()
{
System.out.println("total books registered: " + BookList.size());
System.out.println("ISBN | Name | Author | Age Group");
for(Book i : BookList.values())
System.out.println(i.getISBN() + " | " + i.getName() + " | " + i.getAuthor() + " | " + i.getAgeGroup());
}
} /* end of conUI */
}
public class Main
{
public static void main(String args[])
{
Lib l = new Lib();
Lib.UI ui = l.new conUI();
ui.Program();
}
}