wm: java

ref: c29750ceb403bfaa8716480b6fdf06f578db21a9
dir: /Main.java/

View raw version
//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.*;
import java.util.regex.*;
import java.io.Console;
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(String un);

	/* 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 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)
	{
		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.");
			return;
		}
		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 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();
	}
}