BookApp

import java.util.ArrayList;
import java.util.List;

// Genre interface defining standard book categories
interface Genre {
    int UNCLASSIFIED = 0, ACTION = 1, COMEDY = 2, HORROR = 3;

    void setGenre(int genre);

    int getGenre();
}

// Interface for objects that support password-based locking
interface PasswordLockable {
    void setPassword(String password);

    void lock(String password);

    void unlock(String password);

    boolean isLocked();
}

// Book class implementation with security and comparison features
class Book implements Genre, PasswordLockable, Comparable<Book> {
    private String bookCode;
    private String title;
    private double price;
    private int genre;
    private String password;
    private boolean booksLocked;

    public Book(String bookCode, String title, double price, int genre) {
        this.bookCode = bookCode;
        this.title = title;
        this.price = price;
        this.genre = genre;
        this.password = "";
        this.booksLocked = false;
    }

    // Unified guard method to handle lock state checks
    private boolean isUpdateAllowed() {
        if (booksLocked) {
            System.out.println("Book is locked, cannot update.");
            return false;
        }
        return true;
    }

    // Encapsulated setters with lock validation
    public void setBookCode(String bookCode) {
        if (isUpdateAllowed())
            this.bookCode = bookCode;
    }

    public String getBookCode() {
        return bookCode;
    }

    public void setTitle(String title) {
        if (isUpdateAllowed())
            this.title = title;
    }

    public String getTitle() {
        return title;
    }

    public void setPrice(double price) {
        if (isUpdateAllowed())
            this.price = price;
    }

    public double getPrice() {
        return price;
    }

    public void setGenre(int genre) {
        if (isUpdateAllowed())
            this.genre = genre;
    }

    public int getGenre() {
        return genre;
    }

    // Security management methods
    public void setPassword(String password) {
        this.password = password;
    }

    public void lock(String password) {
        if (this.password.equals(password)) {
            this.booksLocked = true;
            System.out.println("Book is locked now.");
        } else {
            System.out.println("Invalid password. Book is still unlocked.");
        }
    }

    public void unlock(String password) {
        if (this.password.equals(password)) {
            this.booksLocked = false;
            System.out.println("Book is unlocked now.");
        } else {
            System.out.println("Book is still locked.");
        }
    }

    public boolean isLocked() {
        return booksLocked;
    }

    // Map integer constant to human-readable genre name
    public String getGenreText() {
        return switch (genre) {
            case ACTION -> "Action";
            case COMEDY -> "Comedy";
            case HORROR -> "Horror";
            default -> "Unclassified";
        };
    }

    // Price-based comparison for sorting and searching
    @Override
    public int compareTo(Book other) {
        return Double.compare(this.price, other.price);
    }

    // Formatted string representation of the book record
    @Override
    public String toString() {
        return String.format("Book code: %-6s Title: %-20s Price: %10.2f Genre: %s",
                bookCode, title, price, getGenreText());
    }
}

// Application entry point for record processing
public class BookApp {
    public static void main(String[] args) {
        System.out.println("Creating 4 book records:");
        Book[] books = {
                new Book("A001", "Unknown Title", 0.00, Genre.UNCLASSIFIED),
                new Book("B002", "Ocean Heart", 150.75, Genre.COMEDY),
                new Book("C003", "Cave", 180.59, Genre.HORROR),
                new Book("D004", "Master", 211.39, Genre.ACTION)
        };

        for (Book b : books)
            System.out.println(b);

        // Security feature test sequence
        System.out.println("\nSet up a password. The password is PASS123");
        books[0].setPassword("PASS123");
        System.out.println("A password has been set up.");
        System.out.println("\nFirst book record is: " + books[0]);

        System.out.println("\nLock the first book record using PASS123");
        books[0].lock("PASS123");

        System.out.println("\nAttempt to change the price of the 1st book.");
        books[0].setPrice(211.39);

        System.out.println("\nTry to unlock it with a wrong password.");
        books[0].unlock("WRONG");

        System.out.println("\nNow use PASS123 to unlock it.");
        books[0].unlock("PASS123");

        // Record update sequence
        System.out.println("\nThe first book's title, price, and genre have been updated:");
        books[0].setTitle("A movie.");
        books[0].setPrice(211.39);
        books[0].setGenre(Genre.ACTION);
        System.out.println(books[0]);

        // Efficient single-pass search for all records sharing the maximum price
        System.out.println("\nList of books that have the highest price:");
        List<Book> topPricedBooks = new ArrayList<>();
        double maxPrice = -1.0;

        for (Book b : books) {
            if (b.getPrice() > maxPrice) {
                maxPrice = b.getPrice();
                topPricedBooks.clear();
                topPricedBooks.add(b);
            } else if (Math.abs(b.getPrice() - maxPrice) < 0.001) {
                topPricedBooks.add(b);
            }
        }

        topPricedBooks.forEach(System.out::println);
    }
}

 

Scroll to Top