Scenario & SetupS2C Home « Scenario & Setup

In the first lesson of the case study we look at a project proposal and set up our environment. We start by looking at information gathered from the stake holder who we shall call 'Stocking Goods Limited' and how this can be translated into a multi tiered user application fit for purpose. With the basic requirements of the project proposal analysed we can build the file structure for our source and class files. We finish the lesson by writing code to create a Manufacturer test file to be used with the Case Study.

Project Proposalgo to top of page Top

Stocking Goods Limited are a wholesaler of general goods that are stocked from various locations around the country. Each day they stock the goods required to fulfill orders from customers invoices. Currently this is achieved by several clerks who tally up invoices and call the various manufacturers who stock the goods required.

As the company has grown and the number of invoices and stock to order has increased, the manual user processes are becoming more error prone and Stocking Goods Limited want a new user system to automate invoice calculation and stock purchasing. They have decided that the invoice calculation processes are more involved and can be deferred to the second phase of automation. For the initial phase of the project they want the stock purchasing side of the business automated.

Information forwarded by Stocking Goods Limited includes the file structure of the Manufacturer data file whose format musn't be changed and an interface that must be implemented without amendments. The reasoning behind this is that another project group are working in tandem on a reporting system and Stocking Goods Limited have provided both projects with the format of a Manufacturer data file and a Stock interface that must be implemented as is.

The project will be written using Java technology only and must implement the following features:

  • A client application that uses a GUI written in Swing which connects to the Manufacturer data file and can be run in networked or non-networked mode. This will be achieved using the following command line arguments appended to our startup application:
    1. "client" - Run the application in non-networked mode so that access to the Manufacturer data file from the GUI runs in the same JVM and doesn't include any networking or serialization of objects.
    2. "" (no argument) - Run the application in networked mode so that access to the Manufacturer data file from the GUI runs in a different JVM and includes networking and serialization of objects.
  • Network server functionality that allows access to the Manufacturer data file remotely using RMI-JRMP. This will be achieved using the following command line argument appended to our startup application:
    1. "server" - Run the application in server mode with functionality that provides the logic for displaying configurable objects and starting and exiting the server in a safe manner.
  • Access to the Manufacturer data file must include search, stocking and unstocking functionality and provide record locking for the Manufacturer data file as specified in the Stock interface.
    • Search functionality should include the capability to search by name, by location, by name and location or search all records.
    • Stocking orders should only occur once. If the amount entered is wrong the goods will have to be unstocked and the correct stock order reentered.
    • Stocking Goods Limited do not anticipate more than one program having concurrent access to the Manufacturer data file as the reporting system will be run in batch overnight. So our locking only needs to deal with multiple concurrent clients using the server.
  • The code needs to be self documenting and the Javadoc tool will be run on project completion to produce system documentation.
    • We write doc comments in HTML and these must precede a class, field, constructor or method declaration. Doc comments are made up of a description followed by block tags which are the names of parameters, return types, pointers etc. (@param, @return, and @see are examples of block tags).

Manufacturer File Formatgo to top of page Top

Stocking Goods Limited have provided us with the format of the Manufacturer file they want us to use although there is no test file provided. We will have to create a Manufacturer test file ourselves which we do in Create Manufacturer File below.

Field Length Type Description Comments
Header Information
4 byteintManufacturer File numberIn the range -2,147,483,648 to 2,147,483,647
Record Information (repeated to EOF)
1 byteStringManufacturer record deleted field'0' - Current record, '1' - Deleted record.
30 byteStringManufacturer name fieldThe name of the manufacturer.
30 byteStringManufacturer location fieldThe town where the manufacturer is located.
40 byteStringManufacturer product description fieldThe name of the product.
8 byteStringManufacturer product price fieldThe price of the product. Format nnnnn.nn
3 byteStringManufacturer product stock level fieldValid ranges 0-999.
3 byteStringManufacturer product stock ordered fieldValid ranges 1-999. Must not be > stock level.

Stocking Goods Limited have requested that we create a class representing the record information within the Manufacturer file called unsuprisingly Manufacturer as they see a lot of future reuse of this file and it will also be helpful when implementing the Stock interface.

A Manufacturer object should be a representation of the Manufacturer file record information in an object oriented framework, allowing easy access to fields.

Stock Interfacego to top of page Top

The following Stock interface will be used in other projects and so must be implemented as is. The interface provides the contract for the CRUD operations for the Manufacturer file as well as templates for the search and locking/unlocking mechanisms.

Stocking Goods Limited have also included doc comments for the interface which are written in HTML and can be turned into a document at a later date using the Javadoc tool. As requested by the stakeholder, we will have to also provide doc comments for all class, field, constructor and method declarations.


package model;

/**
 * An interface implemented by classes that provide use of the Manufacturer file.
 * 
 */
public interface Stock {
	
	/**
	 * Creates a new record in the Manufacturer file which could be a deleted
	 * entry. Inserts the given Manufacturer data, and returns the record
	 * number of the new record.
	 * 
	 * @param manufacturerData An array of Manufacturer data fields.
	 * 
	 * @return The record number of the Manufacturer record created.
	 * @throws DuplicateKeyException Record already exists.
	 */
	public long createRecord(String[] manufacturerData) throws DuplicateKeyException;
	
	/**
	 * Reads a record from the Manufacturer file and returns a String
	 * array where each element is a Manufacturer field value.
	 * 
	 * @param recNo A record number denoting the byte location in the 
	 * Stock file where this Manufacturer record starts.
	 * 
	 * @return A String array containing the fields of the 
	 * Manufacturer record.
	 * 
	 * @throws RecordNotFoundException Indicates the record was not found.
	 */
	public String[] readRecord(long recNo) throws RecordNotFoundException;
	
	/**
	 * Modifies the fields of a Manufacturer record. The new value for field n 
	 * appears in manufacturerData[n]. Throws a SecurityException if the record 
	 * is locked with a number other than lockRecord.
	 * 
	 * @param recNo The record number of the product record to read.
	 * @param manufacturerData A String array of Manufacturer fields.
	 * @param lockRecord The lock value.
	 * 
	 * @throws RecordNotFoundException Indicates the record was not found.
	 * @throws SecurityException Indicates a lock record mismatch.
	 */
	public void updateRecord(long recNo, String[] manufacturerData, long lockRecord)
			throws RecordNotFoundException, SecurityException;
	
	/**
	 * Deletes a record, making the record number and associated disk storage
	 * available for reuse. Throws SecurityException if the record is locked
	 * with a number other than lockRecord.
	 * 
	 * @param recNo The record number of the product record to read.
	 * @param lockRecord The lock value.
	 * 
	 * @throws RecordNotFoundException Indicates the record was not found.
	 * @throws SecurityException Indicates a lock record mismatch.
	 */
	public void deleteRecord(long recNo, long lockRecord)
			throws RecordNotFoundException, SecurityException;

	/** 
	 * Returns an array of record numbers that match the specified search. Field n 
	 * in the Manufacturer file is described by searchCriteria[n]. A null value in 
	 * searchCriteria[n] matches any field value. A non-null value in 
	 * searchCriteria[n] matches any field value that begins with searchCriteria[n]. 
	 *
	 * @param searchCriteria The search criteria for retrieving records.
	 * 
	 * @return A long array of manufacturer record numbers
	 * matching the search criteria.
	 */
	public long[] findBySearchCriteria(String[] searchCriteria);

	/**
	 * Locks a record so that it can only be updated or deleted by this client.
	 * Returned value is a number that must be used when the record is unlocked,
	 * updated, or deleted. If the specified record is already locked by a
	 * different client, the current thread goes into a wait state until the 
	 * record is unlocked.
	 * 
	 * @param recNo The record number of the Manufacturer record to lock.
	 * 
	 * @return The record number of the locked Manufacturer record.
	 * @throws RecordNotFoundException Indicates the record was not found.
	 */
	public long lockRecord(long recNo) throws RecordNotFoundException;

	/** Releases the lock on a record. Lock number must be the same as the number
	 * returned when the record was locked; otherwise throws SecurityException.
	 * 
	 * @param recNo The record number of the Manufacturer record to unlock.
	 * 
	 * @return A long value denoting the generated lock number.
	 * 
	 * @throws SecurityException Indicates a lock record mismatch.
	 */
	public void unlock(long recNo, long lockRecord) throws SecurityException;
}

Proposal Conclusionsgo to top of page Top

After reading through the information supplied to us by Stocking Goods Limited we can draw certain conclusions:

  1. We will be using a package called model to store the supplied Stock interface in.
  2. We will need to implement the Stock interface and shall call the implementation class StockImpl.
  3. We will need to create some exception classes in the model package, to honour the contract of the Stock interface, these being DuplicateKeyException, RecordNotFoundException and SecurityException.
    • A situation might also arise where a user tries to stock goods that have already been stocked by another user and if this happens we will need to throw an exception which we will call StockingException.
  4. The Manufacturer file, Stocking Goods Limited have asked us to create, will also go in the model package.
  5. We will also be creating a new GUI and will be accessing services locally and also remotely using RMI-JRMP. This scenario fits in well with the MVC pattern and so we will use this pattern for the project.
  6. As we are using the MVC pattern we will place all our GUI code into a client package.
  7. As we are using RMI-JRMP and will have local and remote services we can place our controller code into services and remoteservices packages.
  8. If we are running in server mode we will need to include a Swing panel to automate information gathering for the remote location of the Manufacturer file used as well as a port number. We can then use this information to create and register a remote connection using RMI-JRMP for our remote clients to connect to.
  9. We will need to seamlessly connect local or remote clients and therefore will have to include Swing panels to automate information gathering for the location of the Manufacturer file used as well as a port number if we are running remotely. If fact the file information is common to all three run modes so we can use the same Swing panel and include a port number where appropraite.
  10. Stocking Goods Limited hava requested functionality to search, stock and unstock the Manufacturer file and these services must be available to local and remote clients.

Project Setupgo to top of page Top

In this part of the lesson we create our project file structure including all the Java source and class files folders required for the Case Study.

The first thing we are going to do in our setup for the Case Study is to make a base folder called _Case_Study in the root directory of our hard drive which we can put all our other folders into.

Lets create a folder for our Case Study files, in Windows this would be:

double click My Computer icon

double click C:\ drive (or whatever your local drive is)

right click the mouse in the window

from the drop down menu select New

click the Folder option and call the folder _Case_Study and press enter.

Within the _Case_Study folder we will create separate folders to hold our source files and our compiled byte code and these will be called src and classes.

So after creating these folders your directory structure should look something like the following screenshot:

directory structure

Creating Our Package Foldersgo to top of page Top

Now we need create folders for our packages within the src directory, we don't need to do this for our classes directory, as this can done during compilation of our code using the -d option, which we will discuss when we compile.

We worked out in the last lesson after investigating the proposal that we need packages for:

  1. The code to process the manufacturer file and requests sent from users of the GUI, which is the model element of the MVC pattern.
  2. The client code, which is our GUI and is the view element of the MVC pattern.
  3. The services code, which incorporates our local and remore services and is the controller element of the MVC pattern.
  4. We will also need a package for placing our testing classes in.

Ok, lets create these five new folders: model, view, services, remoteservices and testing within our src folder.

So after creating these folders your src folder directory structure should look something like the following screenshot:

directory structure

That's all we need to do as far as setting up the folder packages for the project goes.

Create Manufacturer Filego to top of page Top

In this part of the lesson we write the code to create a test Manufacturer file to be used with the Case Study. We want the file to have a single header record with a Manufacturer file number, followed by data records that contain the record information repeated until the end of the file.

Stocking Goods Limited have provided us with the format of the Manufacturer file they want us to use, as shown above in Manufacturer File Format, although there is no test file provided.

Manufacturer File Creationgo to top of page Top

Using the information, as shown above in Manufacturer File Format, we can create a simple Manufacturer file that should be fit for purpose when coding the rest of the case study.

NOTE: The pathnames used in all the examples for the case study are using a Windows operating system, so if you are using Unix or another operating system adjust them accordingly.

This also applies to code such as:


static String pathname = "C:\\_Case_Study\\src\\manufacturerTest.txt";

Which is used in the example below and you may have to adjust for your operating system.

Cut and paste the following code into your text editor and save it in the   c:\_Case_Study\src\testing directory. We have covered all the code below in the other sections of the site apart from the RandomAccessFile file which allows reading, writing and byte location via a pointer and the self documenting HTML tags we have added for the Javadoc tool, which will be run on project completion to produce system documentation.


package testing;

import java.io.IOException;
import java.io.RandomAccessFile;

public class CreateManufacturerFile {
    /**
     * The pathname for the Manufacturer file we are going to create.
     */
    static String pathname = "C:\\_Case_Study\\src\\manufacturertestfile.txt";
    /**
     * The Manufacturer file.
     */
    static RandomAccessFile manufacturerFile;
    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            // Create Manufacturer file and header
            manufacturerFile = new RandomAccessFile(pathname, "rw");
            int fileNumber = 1234;
            manufacturerFile.writeInt(fileNumber);
            // Create Manufacturer records
            String[] createArray = {" ", "Smart Clothes Incorporated", "Tooting", 
                    "Blue Trousers", "12.99", "308", "52"};
            passManufacturerFields(createArray);
            String[] createArray1 = {" ", "Smart Clothes Incorporated", "Swindon", 
                    "Red Checked Cotton Shirt", "21.99", "627", " "};
            passManufacturerFields(createArray1);
            String[] createArray2 = {" ", "Fine Fancy Foods", "Birmingham", 
                    "Chrismas Pudding", "7.99", "627", "12"};
            passManufacturerFields(createArray2);
            String[] createArray3 = {" ", "Car Parts Ltd", "Swindon", 
                    "Front Axle", "222.49", "5", " "};
            passManufacturerFields(createArray3);
            String[] createArray4 = {" ", "Fine Fancy Foods", "Swindon", 
                    "Crispy Duck", "5.99", "72", " "};
            passManufacturerFields(createArray4);
            String[] createArray5 = {" ", "Smart Clothes Incorporated", "Birmingham", 
                    "Blue Jeans", "29.99", "123", "7"};
            passManufacturerFields(createArray5);
            String[] createArray6 = {" ", "Smart Clothes Incorporated", "Chester", 
                    "Pink Scarf", "2.99", "722", " "};
            passManufacturerFields(createArray6);
            String[] createArray7 = {" ", "Fine Fancy Foods", "Chester", 
                    "Smoked Salmon", "9.99", "422", " "};
            passManufacturerFields(createArray7);
            String[] createArray8 = {" ", "Smart Clothes Incorporated", "Braintree", 
                    "Top Hat", "79.99", "29", "2"};
            passManufacturerFields(createArray8);
            String[] createArray9 = {" ", "Car Parts Ltd", "Birmingham", 
                    "Back Axle", "252.99", "8", " "};
            passManufacturerFields(createArray9);
            String[] createArray10 = {" ", "Fine Fancy Foods", "Braintree", 
                    "Strawberry Cheesecake", "2.99", "999", " "};
            passManufacturerFields(createArray10);
            String[] createArray11 = {" ", "Car Parts Ltd", "Tooting", 
                    "Windscreen Wipers", "12.99", "278", " "};
            passManufacturerFields(createArray11);
            String[] createArray12 = {" ", "Fine Fancy Foods", "Tooting", 
                    "Quiche Lorraine", "4.99", "812", "127"};
            passManufacturerFields(createArray12);
            manufacturerFile.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * This method passes a Manufacturer data field for writing.
     *
     * @param A String array holding Manufacturer information.
     */
    private static void passManufacturerFields(String[] manufacturerArray) 
            throws IOException {
        String s = "";
        // Pass string array to write out
        for (int i=0; i<7; i++) {
            s = manufacturerArray[i];
            writeBytesToFile(i, s);
        }
    }

    /**
     * This method populates the Manufacturer file and pads each field.
     *
     * @param fieldNumber A number denoting field to populate.
     * @param field The data to populate field with.
     */
    private static void writeBytesToFile(int fieldNumber, String field) 
            throws IOException {
        int spaceWrite = 0;
        String s = " ";
        // Populate Manufacturer data record
        switch (fieldNumber) {
            case 0:
                manufacturerFile.writeBytes(field); 
                break;
            case 1:
            case 2:
                manufacturerFile.writeBytes(field); 
                spaceWrite = 30 - field.length();
                for (int i=0; i<spaceWrite; i++) {
                    manufacturerFile.writeBytes(s); 
                }
                break;
            case 3:
                manufacturerFile.writeBytes(field); 
                spaceWrite = 40 - field.length();
                for (int i=0; i<spaceWrite; i++) {
                    manufacturerFile.writeBytes(s); 
                }
                break;
            case 4:
                manufacturerFile.writeBytes(field); 
                spaceWrite = 8 - field.length();
                for (int i=0; i<spaceWrite; i++) {
                    manufacturerFile.writeBytes(s); 
                }
                break;
            case 5:
            case 6:
                manufacturerFile.writeBytes(field); 
                spaceWrite = 3 - field.length();
                for (int i=0; i<spaceWrite; i++) {
                    manufacturerFile.writeBytes(s); 
                }
                break;
            default:
                System.out.println("Erroneous field!");
        }
    }
}

Compiling Our Source File With the -d Option

Open your command line editor:

Change to directory  cd c:\_Case_Study\src\testing

Compile CreateManufacturerFile.java using the java compiler with the -d option
  javac -d ..\..\classes CreateManufacturerFile.java

What we are saying with the -d option is that we want our compiled bytecode to go into the classes directory which is two directories above this directory. The following screenshot shows the javac command and the contents of the classes directory after the compile. Because we have used a package (package testing;) at the top of the code the compiler has created this directory within the classes directory. When we look in the testing directory we can see the compiled CreateManufacturerFile.class file.

compile create man file

Running The Packaged CreateManufacturerFile class

Run the CreateManufacturerFile class from the classes directory using our package as well (java testing.CreateManufacturerFile). We should now have a test Manufacturer file ready to use within the src directory called manufacturertestfile.txt as shown in the screenshot below.

run create man file

Lesson 1 Complete

That's it for the Scenario & Setup lesson in which we read a project proposal and made some conclusions from it, setup up some directories for the project and created a test Manufacturer file.

Related Java6 Tutorials

Beginning Java6 - Primitive Variables
Beginning Java6 - Conditional Statements
Beginning Java6 - Loop Statements
Objects and 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 - Methods
Objects & Classes - Static Members
OO Concepts - Interfaces
Flow Control - Handling Exceptions
Flow Control - Declaring Exceptions
API Contents - Inheritance - Using the package keyword
API Contents - Inheritance - Using the import keyword
Swing - Gui Concepts
Swing - RMI

What's Next?

In the next lesson we set up the first part of the model elements of the MVC pattern that can be derived from the project proposal.

go to home page Homepage go to top of page Top