Search code examples
javajsfdesign-patternsicefaces

Java Design: Locking and Monitor reports


I have the following requirement.

Introduction

The system is report/content management system. It allows user to do CRUD operations on reports.

Business Logic/UI Component

When a user is editing a report, other users can't edit the report but view only.

It contains a page with a table that monitor the locked report for view.

Challenger

1) How should I implement this "locking" Mechanism ? 2) What are the design pattern and API that will assist me?

My current implementation

I will have a report service class It will contain a hashmap of all the reports that are locked(with information of user for lock management)

I have completed SCJD and was considering using my lock mechanism, but I realize I do not need the wait "locking".

The only problem I worried is concurrency issue when "locking" the report(adding the lock into map), I believe that can be easily solve by using synchronization.

For the monitoring of locked report table, I plan to implement observer pattern in the report service class. For each user/backingbean it will "subscribe" to the report service.

Any inputs? ????


Solution

  • Answer is simple... We can manage this problem with 2 classes.

    Features of each class is given below

    ReportUtil:
    (1) track whether any report is open in write mode
    (2) create object of report based on access mode available

    Report:
    (1) open read only or writable report based on access given
    (2) While closing, reset the flag in ReportUtil class, if the current report was open in write mode.

    Client:
    To test ReportUtil and Report classes.


    import java.util.LinkedList;
    
    public class ReportUtil {
    
        private static boolean bIsWriteLockAvaialable = true;
    
        public static synchronized Report getReport() {
            Report reportObj = new Report(bIsWriteLockAvaialable);
            if(true == bIsWriteLockAvaialable) {
                bIsWriteLockAvaialable = false;
            }
            return reportObj;
        }   
    
        public static void resetLock() {
            bIsWriteLockAvaialable = true;
        }
    }
    

    public class Report {
        private boolean bICanWrite = false;
    
        public Report(boolean WriteAccess) {
            bICanWrite = WriteAccess;
        }
    
        public void open() {
            if(bICanWrite == true) {
                //Open in write mode
                System.out.println("Report open in Write mode");
            }
            else {
                //Open in readonly mode
                System.out.println("Report open in Read only mode");
            }
        }
    
        public synchronized void close() {
            if(bICanWrite == true) {
                ReportUtil.resetLock();
            }
        }
    }
    

    public class Client {
    
        public static void main(String[] args) {
            Report report1 = ReportUtil.getReport();
            report1.open(); //First time open in writable mode
    
            Report report2 = ReportUtil.getReport();
            report2.open(); //Opens in readonly mode
    
            Report report3 = ReportUtil.getReport();
            report3.open(); //Opens in readonly mode
    
            report1.close(); //close the write mode
    
            Report report4 = ReportUtil.getReport();
            report4.open(); //Opens in writable mode since the first writeable report was closed
        }
    
    }
    

    Output: Report open in Write mode Report open in Read only mode Report open in Read only mode Report open in Write mode


    I don't know why we want to use Hash table here. May be I didn't understand your requirement. Also, I have used synchronized methods to escape from synchronization problems.

    If your requirement was to track all the users who are using the report, please let me know.

    Happy Learning!!!