Model Part 2J8 Home « Model Part 2
In this lesson of the case study we finish writing and compiling the model code. To do this we will have to add some imports to the StockImpl
class and complete the method stubs we left
for this section of the case study. We will start by completing the search()
method and finish the model code by updating the stocking()
and unstocking()
method.
Search Functionality Top
In the first part of the lesson we add imports to the StockImpl
class so we can pass back a table model to our users as well as handling exceptions from our services. We then add the
functionality to the search()
method for passing back search results via the table model to populate the Manufacturer Panel we
sketched out in View Part 1 - Designing The GUI.
Updating The StockImpl
Class Top
The first thing we need to do is add a couple of imports to the top of the StockImpl
class after the existing imports.
import client.ManufacturerTableModel;
import services.ServicesException;
Open the StockImpl
class in your text editor and cut and paste the above imports to the top of the StockImpl
class after the existing imports.
Updating The search()
Function
We also need to update the search()
function stub so it now returns a ManufacturerTableModel
containing all Manufacturer records pertaining to search criteria. We also need
to code the method to retrieve this information.
/**
* Search manufacturer file via criteria entered by a user in the GUI.
*
* @param name The name of the Manufacturer.
* @param location The location where the Manufacturer is based.
* @return A ManufacturerTableModel containing all Manufacturer records pertaining to
* search criteria.
*
*/
public ManufacturerTableModel search(String name, String location) {
log.entering("StockImpl", "search",
new Object[]{name, location});
ManufacturerTableModel modelStockImpl = new ManufacturerTableModel();
long[] retrecOffsets = new long[500];
String[] criteria = {name, location};
// Use search criteria to return an array of record numbers (500 more than enough)
retrecOffsets = findBySearchCriteria(criteria);
// Now read manufacturers from cache map using returned record numbers
try {
for (long recOffset : retrecOffsets) {
// Exit loop when no more records to process
if (recOffset == 0) {
break;
}
Manufacturer manufacturer = getManufacturer(recOffset);
modelStockImpl.addManufacturerRecord(manufacturer);
}
} catch (RecordNotFoundException e) {
log.log(Level.SEVERE, e.getMessage(), e);
throw new ServicesException(e);
}
log.exiting("ServicesImpl", "search");
return modelStockImpl;
}
In not already open, open the StockImpl
class in your IDE and cut and paste the above search()
method into the StockImpl
class overwriting the
existing search()
method and comments. The search()
method can be found at the very bottom of the StockImpl
class.
Stock FunctionalityTop
In this part of the lesson we finish the model code for the case study by completing the stocking()
and unstocking()
methods requested by Stocking Goods Limited. These
methods are delegated to, via the Services
singleton, whenever a user requests stocking or unstocking within the Manufacturer Application GUI.
Updating The stocking()
Method Top
The stocking()
method stub needs to be coded to accept a stocking amount entered in the Manufacturer GUI. We will have to update the information held in our cache map and also update
the physical Manufacturer file held on disk. We must also ensure that the stock ordered hasn't been set by another user, before setting our locks and updating the information.
Open the StockImpl
class in your text editor and cut and paste the following stocking()
method into the StockImpl
class overwriting the
existing stocking()
method and comments. The stock()
method can be found near the bottom of the StockImpl
class.
/**
* Stock the requested amount entered by a user in the GUI.
*
* @param name The name of the Manufacturer.
* @param location The location where the Manufacturer is based.
* @param stockLevel The amount of stock left.
* @param stockOrdered The amount of stock requested.
*
* @throws StockingException Stock quantity already ordered by another user.
*
*/
public void stocking(String name, String location,
int stockLevel, int stockOrdered) throws StockingException {
log.entering("StockImpl", "stocking",
new Object[]{name, location, stockLevel, stockOrdered});
Long lock = 0L;
long[] retrecOffset = new long[1];
String[] criteria = {name, location};
boolean unlockRequired = true;
retrecOffset = findBySearchCriteria(criteria);
// Return the record number
long recOffset = retrecOffset[0];
if (recOffset == 0) {
log.log(Level.INFO, "Problem stocking Manufacturer: " + name + ", " + location);
String e = "Problem stocking Manufacturer: " + name + ", " + location;
throw new ServicesException(e);
}
try {
log.log(Level.FINE, "Run by: " + Thread.currentThread().getName());
Manufacturer manufacturer = getManufacturer(recOffset);
// Firstly make sure that stock ordered hasn't been set by another user
if (!manufacturer.getStockOrdered().equals("")) {
log.log(Level.INFO, "Manufacturer: " + name + ", " + location +
" , " + " product: " + manufacturer.getProduct() +
", stock quantity already ordered by another user.");
unlockRequired = false;
throw new ServicesException("Stock quantity already ordered by another user.");
} else {
String strStockLevel = "" + stockLevel;
manufacturer.setStockLevel(strStockLevel);
String strStockOrdered = "" + stockOrdered;
manufacturer.setStockOrdered(strStockOrdered);
String[] manufacturerData = {manufacturer.getDeletedFlag(), manufacturer.getName(),
manufacturer.getLocation(), manufacturer.getProduct(),
manufacturer.getPrice(), manufacturer.getStockLevel(),
manufacturer.getStockOrdered()};
//Add record number to the locking map
lock = lockRecord(recOffset);
//Update record with new stock totals
updateRecord(recOffset, manufacturerData, lock);
log.log(Level.INFO, "Manufacturer: " + name + ", " + location +
" product: " + manufacturer.getProduct() +
" stock quantity left: " + stockLevel +
", stock quantity ordered: " + stockOrdered);
}
} catch (ServicesException e) {
log.log(Level.WARNING, e.getMessage(), e);
throw new StockingException(e);
} catch (ManufacturerFileAccessException | RecordNotFoundException | SecurityException e) {
log.log(Level.SEVERE, e.getMessage(), e);
throw new ServicesException(e);
} finally {
if (unlockRequired) {
//Remove record number from the locking map
unlock(recOffset, lock);
}
}
log.exiting("StockImpl", "stocking");
}
Updating The unstocking()
Method Top
The unstocking()
method stub needs to be coded to accept an unstocking amount entered in the Manufacturer GUI. We will have to update the information held in our cache map and also update the physical
Manufacturer file held on disk. We must also ensure that the unstocking hasn't already been done by another user, before setting our locks and updating the information.
In not already open, open the StockImpl
class in your text editor and cut and paste the above unstocking()
method into the StockImpl
class overwriting the
existing unstocking()
method and comments. The unstocking()
method can be found near the bottom of the StockImpl
class just below the stocking()
method.
/**
* Unstock the requested amount entered by a user in the GUI.
*
* @param name The name of the Manufacturer.
* @param location The location where the Manufacturer is based.
* @param stockOrdered The amount of unstocking to do.
*
*/
public void unstocking(String name, String location, int stockOrdered) {
log.entering("StockImpl", "unstocking",
new Object[]{name, location, stockOrdered});
Long lock = 0L;
long[] retrecOffset = new long[1];
String[] criteria = {name, location};
boolean unlockRequired = true;
retrecOffset = findBySearchCriteria(criteria);
// Return the record number
long recOffset = retrecOffset[0];
if (recOffset == 0) {
log.log(Level.INFO, "Problem restocking Manufacturer: " + name + ", " + location);
String e = "Problem restocking Manufacturer: " + name + ", " + location;
throw new ServicesException(e);
}
try {
log.log(Level.FINE, "Run by: " + Thread.currentThread().getName());
Manufacturer manufacturer = getManufacturer(recOffset);
// Firstly make sure that ordered stock hasn't been cancelled by another user
if (manufacturer.getStockOrdered().equals("")) {
log.log(Level.INFO, "Manufacturer: " + name + ", " + location +
" , product: " + manufacturer.getProduct() +
" stock quantity ordered, already reset by another user.");
unlockRequired = false;
} else {
//Restock manufacturer and remove stock ordered
int manStockLevel = 0;
try {
manStockLevel = Integer.parseInt(manufacturer.getStockLevel());
} catch (NumberFormatException e) {
log.log(Level.INFO, "Manufacturer: " + name + ", " + location +
", " + " stock level was non numeric");
} finally {
manStockLevel = manStockLevel + stockOrdered;
String strStockLevel = "" + manStockLevel;
manufacturer.setStockLevel(strStockLevel);
manufacturer.setStockOrdered("");
String[] manufacturerData = {manufacturer.getDeletedFlag(),
manufacturer.getName(), manufacturer.getLocation(),
manufacturer.getProduct(), manufacturer.getPrice(),
manufacturer.getStockLevel(), manufacturer.getStockOrdered()};
//Add record number to the locking map
lock = lockRecord(recOffset);
//Update record with new stock totals
updateRecord(recOffset, manufacturerData, lock);
log.log(Level.INFO, "Manufacturer: " + name + ", " + location +
", product: " + manufacturer.getProduct() +
", new Stock Level: " + manufacturer.getStockLevel());
}
}
} catch (ManufacturerFileAccessException | RecordNotFoundException | SecurityException e) {
log.log(Level.SEVERE, e.getMessage(), e);
throw new ServicesException(e);
} finally {
if (unlockRequired) {
//Remove record number from the locking map
unlock(recOffset, lock);
}
}
log.exiting("StockImpl", "unstocking");
}
After updating the StockImpl
class your model
package should look similar to that in the screenshot below.
Lesson 12 Complete
In this lesson we finished coding the Model elements of the MVC pattern for our case study.
Related Java Tutorials
Fundamentals - Primitive Variables
Fundamentals - Conditional Statements
Fundamentals - if
Construct
Objects & Classes - Arrays
Objects & Classes - Class Structure and Syntax
Objects & Classes - Reference Variables
Objects & Classes - Methods
Objects & Classes - Instance Variables & Scope
Objects & Classes - Constructors
Objects & Classes - Static Members
Objects & Classes - Enumerations
OO Concepts - Encapsulation
OO Concepts - Inheritance Concepts - Using the super
keyword
Swing - RMI - Serialization
Exceptions - Handling Exceptions
API Contents - Inheritance - Using the package
keyword
API Contents - Inheritance - Using the import
keyword
Concurrency - Synchronization - Synchronized Blocks
What's Next?
In the next section we code the remote services Controller elements of the MVC pattern for our case study.