vault backup: 2024-03-05 13:01:43
This commit is contained in:
@@ -1,22 +1,27 @@
|
||||
|
||||
/**
|
||||
* Write a description of class Library here.
|
||||
* Class to create objects of a Library, which can hold and report on assets held within
|
||||
*
|
||||
* @author (your name)
|
||||
* @version (a version number or a date)
|
||||
* @George Wilkinson
|
||||
* @2.0
|
||||
*/
|
||||
|
||||
// Import all required libraries. Not using .* as it is not good practice due to potential conflicts.
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Scanner;
|
||||
import java.util.Random;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.awt.FileDialog;
|
||||
import java.awt.Frame;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class Library
|
||||
{
|
||||
private ArrayList<LibraryItem> itemList; // Initialise an ArrayList of name itemList to store LibraryItems
|
||||
private ArrayList<LibraryItem> itemList; // Initialise an ArrayList of name itemList to store Library Items
|
||||
private ArrayList<LibraryUser> userList; // Initialise an ArrayList of name userList to store Library Users
|
||||
private HashSet<String> uuidSet; // Initialise a Hash Set of name uuidSet ( unique user identifier ) to store unique user IDs for efficient O(1) searching
|
||||
|
||||
/*
|
||||
* Constructor for objects of class Library
|
||||
@@ -24,6 +29,8 @@ public class Library
|
||||
public Library()
|
||||
{
|
||||
itemList = new ArrayList<LibraryItem>();
|
||||
userList = new ArrayList<LibraryUser>();
|
||||
uuidSet = new HashSet<String>();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -35,17 +42,110 @@ public class Library
|
||||
}
|
||||
|
||||
/*
|
||||
* Prints to the terminal all items in the itemList
|
||||
* Appends a LibraryUser to the userList.
|
||||
*/
|
||||
public void printAllItems()
|
||||
public void storeUser( LibraryUser user )
|
||||
{
|
||||
for( LibraryItem item : itemList )
|
||||
userList.add( user );
|
||||
if ( user.getUserID().equals( "unknown" ) )
|
||||
{
|
||||
item.printDetails();
|
||||
user.setUserID( generateUserID( "AB-", 6 ) );
|
||||
}
|
||||
}
|
||||
|
||||
public void readItemData() //throws IOException
|
||||
/*
|
||||
* Returns a random unique user ID by specifying
|
||||
* @prefix - arbitrary alphanumeric prefix
|
||||
* @length - length of numeric ID
|
||||
* and returning a unique user id
|
||||
* @uuid - a unique string starting with @prefix, and concat. with a random number
|
||||
*
|
||||
* Example: length = 6, expected result should be under 999,999 and above 99,999.
|
||||
* If we just use 10^(length), this would generate any number under 1,000,000.
|
||||
* This is an issue since any integers below 100,000 can be used, which would be incorrect.
|
||||
* By using the offset of a factor of 10 below the desired length we can generate between 0 and 899,999.
|
||||
* After this, we can add 100,000 back to the number to ensure a baseline length is maintained.
|
||||
*
|
||||
* Note: I am aware that this is overengineered, and that several random integers of amount @length could be used,
|
||||
* but this is considerably more efficient since there is no iteration involved in the creation of the ID. O(1)
|
||||
*/
|
||||
public String generateUserID( String prefix, int length )
|
||||
{
|
||||
Random random = new Random();
|
||||
final int offset = (int) Math.pow( 10, (length-1) ); // Static integer equal to 10^(length-1) lower than length. This will allow for the factor to be consistent.
|
||||
int intLength = (int) ( Math.pow( 10, length ) ) - offset ; // Integer equal to 10^(length) minus the offset. This creates a ceiling for the ID range.
|
||||
|
||||
if ( uuidSet.size() > ( intLength - 1 ) ) { // No idea why I get an error for equals FIX LATER
|
||||
System.out.println("Too many user IDs delegated for current range, increasing ID range by a factor of 10");
|
||||
return generateUserID( prefix, length+1 );
|
||||
/*
|
||||
* This is essential for eliminating a stack overflow error when the specified range is full. This would be incorrect to catch.
|
||||
* By incrementing the length value when the ID range is full, roughly 2.1 billion users can be created without running into an overflow error.
|
||||
*/
|
||||
}
|
||||
|
||||
String uuid = prefix + ( random.nextInt( intLength ) + offset );
|
||||
/*
|
||||
* Sets the uid to the prefix, concat. with a random integer of specified length
|
||||
* Add the offset to a random number, to create a floor to the ID range.
|
||||
*/
|
||||
|
||||
if ( uuidSet.contains( uuid ) )
|
||||
{
|
||||
generateUserID( prefix, length ); // If the ID generated is already contained in the hashset, the method should be called again.
|
||||
}
|
||||
|
||||
uuidSet.add( uuid ); // Add the UUID to the hash set so it cannot be returned from this method more than once.
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/*
|
||||
* A method to output all user data to a file using a fileDialog to specify file location.
|
||||
*
|
||||
* Note: Potentially could implement the HashSet made for GenerateUserID to avoid unnecessary recursion.
|
||||
*/
|
||||
public void writeUserData()
|
||||
{
|
||||
try {
|
||||
Frame frame = null; // Initialise null frame
|
||||
FileDialog fileBox = new FileDialog( frame, "Save", FileDialog.SAVE ); // Initialise file dialog box to save written data.
|
||||
fileBox.setVisible( true );
|
||||
PrintWriter writer = new PrintWriter( new File( fileBox.getDirectory() + fileBox.getFile() ) );
|
||||
for ( LibraryUser user : userList ){
|
||||
user.writeData( writer );
|
||||
}
|
||||
writer.close();
|
||||
}
|
||||
catch( IOException e ) { // Catch any IO Exceptions that may occur from improper file selection.
|
||||
System.err.println( "Caught IOException: " + e.getMessage() + "\nAn I/O Exception has occurred, please check file is readable and correct format." );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Prints to the terminal, in a human-readable format, all items in the itemList
|
||||
*
|
||||
* Contains a marker at the start and end to visualise in terminal output.
|
||||
*/
|
||||
public void printAll()
|
||||
{
|
||||
System.out.println("\n\nStart Detail Print");
|
||||
for( LibraryItem item : itemList )
|
||||
{
|
||||
System.out.println("---------------");
|
||||
item.printDetails();
|
||||
}
|
||||
System.out.println("End Detail Print\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* A method to read all data from files using a fileDialog to specify file location.
|
||||
* This will create the corresponding objects depending on flags contained in the file
|
||||
* and populate it's fields.
|
||||
*
|
||||
* Default flag value: "book", to support legacy files. This will not interfere with
|
||||
* files of different flag orders.
|
||||
*/
|
||||
public void readData()
|
||||
{
|
||||
Frame frame = null; // Initialise a null frame
|
||||
FileDialog fileBox = new FileDialog( frame, "Open", FileDialog.LOAD ); // Initialise filebox with the null frame pointer
|
||||
@@ -53,30 +153,33 @@ public class Library
|
||||
|
||||
try {
|
||||
Scanner fileScanner = new Scanner( new File( fileBox.getDirectory() + fileBox.getFile() ) );
|
||||
String typeFlag = "";
|
||||
String typeFlag = "book"; // Set a default flag to support legacy files.
|
||||
|
||||
while( fileScanner.hasNextLine() ){
|
||||
|
||||
String lineItem = fileScanner.nextLine();
|
||||
//System.out.println( lineItem );
|
||||
|
||||
// Ensure no comments or empty lines are included
|
||||
if ( lineItem.contains( "//" ) || lineItem.trim().isEmpty() ){}
|
||||
|
||||
// Check current line is a candidate flag
|
||||
else if ( lineItem.startsWith("[" ) ) {
|
||||
if ( lineItem.toLowerCase().contains("book") ) {
|
||||
|
||||
if ( lineItem.toLowerCase().contains("book") )
|
||||
typeFlag = "book";
|
||||
//System.out.println( "CHANGED FLAG TO READ BOOKS" );
|
||||
}
|
||||
else if ( lineItem.toLowerCase().contains("periodical") ) {
|
||||
else if ( lineItem.toLowerCase().contains("periodical") )
|
||||
typeFlag = "periodical";
|
||||
//System.out.println( "CHANGED FLAG TO READ PERIODICALS" );
|
||||
}
|
||||
else if ( lineItem.toLowerCase().contains("cd") )
|
||||
typeFlag = "cd";
|
||||
else if ( lineItem.toLowerCase().contains("dvd") )
|
||||
typeFlag = "dvd";
|
||||
else if ( lineItem.toLowerCase().contains("user") )
|
||||
typeFlag = "user";
|
||||
else {
|
||||
System.out.println( "Flag detected, but no accepted format...\n Cannot store item in Library. Changing Flag to generic and skipping the following: ");
|
||||
typeFlag = "generic";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Could be a switch case to be more efficient
|
||||
@@ -96,8 +199,29 @@ public class Library
|
||||
periodical.readItemData( detailScanner );
|
||||
storeItem( periodical );
|
||||
}
|
||||
else if ( typeFlag.equals( "cd" ) ) {
|
||||
//Process CD Data
|
||||
Scanner detailScanner = new Scanner ( lineItem ).useDelimiter(",");
|
||||
LibraryItem cd = new CD();
|
||||
cd.readItemData( detailScanner );
|
||||
storeItem( cd );
|
||||
}
|
||||
else if ( typeFlag.equals( "dvd" ) ) {
|
||||
//Process DVD Data
|
||||
Scanner detailScanner = new Scanner ( lineItem ).useDelimiter(",");
|
||||
LibraryItem dvd = new DVD();
|
||||
dvd.readItemData( detailScanner );
|
||||
storeItem( dvd );
|
||||
}
|
||||
else if ( typeFlag.equals( "user" ) ) {
|
||||
//Process User Data
|
||||
Scanner detailScanner = new Scanner ( lineItem ).useDelimiter(",");
|
||||
LibraryUser user = new LibraryUser();
|
||||
user.readData( detailScanner );
|
||||
storeUser( user );
|
||||
}
|
||||
else if ( typeFlag.equals( "generic" ) ) {
|
||||
// Output unaccepted lines
|
||||
// Output unaccepted lines to terminal
|
||||
System.out.println( lineItem );
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user