CS636 Class 12. domain classes in music1, Getting started on Project 1, HTTP

domain class objects:  equals/hashCode/compareTo.

As provided, the music project domain classes have no equals/hashCode/compareTo methods, and thus rely on Object equals and hashCode.  These are based on the value of the ref to an object, i.e., the memory address of the object in the JVM, a number that is unique to the object.  So if refA == refB, it’s the same object being ref’d.

The default equals and hashCode are consistent, so that if a and b are equals, they have the same hashCodes.  That’s what HashSet and HashMap need for their proper working.

If you overload equals or hashCode, you must overload the other one consistently, or HashSet/HashMap may fail, and anything else that uses both equals and hashCode.

Moral : it’s absolutely fine to leave equals and hashCode unimplemented in almost  any class. If you feel the urge to overload one, proceed cautiously!

If you want to use TreeSet<domainclass>, you need to make the domain class implement Comparable<domainclass>, and thus overload compareTo.  But you must also overload equals consistently, and because of that, overload hashCode consistently too.  See Topping.java for an example. In Topping, it’s nice to use a TreeSet<Topping> with equals based on the string name so that toppings are listed in alphabetic order. 

Another pointer : use @Overload when you do overload these methods, to make sure you’re actually overloading what you think you are. It’s really easy to miss the mark.

Getting started on Project 1, Tour of provided sources
DAO: DbDAO, AdminDAO, DownloadDAO, InvoiceDAO, LineItemDAO: you need to add UserDAO, ProductDAO (and TrackDAO, or handle Tracks in ProductDAO)
Service: Just ServiceException, AdminService, you need to add UserService
Presentation: UserApp, SystemTest: mostly written, you add service calls
Config: MusicSystemConfig: mostly written, uncomment as progress

In DAO, needed next: UserDAO.java, with needed support for registering a user.

For UserDAO class setup, look at InvoiceDAO: package, import, private Connection connection, constructor

Can set UserDAO up with no methods, similarly UserService, build little object graph

Goal 1. Write class-level code for UserService and UserDAO, uncomment them in MusicSystemConfig, run SystemTest without crash.
Problem: are you sure they are really up and working?

How to check that: Write stubs for methods that just print out when they are called:
UserDAO
void insertUser(String email) throws SQLException
{
    System.out.println("insertUser called, email = "+email);
}

UserService
void registerUser(String email) throws ServiceException
{
     System.out.println("registerUser called, email = " +email);
     userDAO.insertUser(email);
}

SystemTest:  call registerUser now for ureg

Goal 2.
SystemTest prints above messages. Now we know we're in business!

Real Code for DAO, Service
What we need: insert a new user. DAO should be generic support as far as possible, so suggest insertUser or createUser
But note that somewhere we need to check if a certain user is already there.  The emails are supposed to be unique, so that's a good thing to check.
So need findUser, given email, plus insertUser and let caller check

You need to do an insert, as you must have done in Register.java, but now we need to use real values and a good PK.
New PK: use col in music_sys_tab:
create table music_sys_tab (
                invoice_id integer not null,   <--see code for using this in InvoiceDAO.java
                user_id integer not null,    <---next user id
                download_id integer not null,
                lineitem_id integer not null);
Want portable id generation (no auto-increment!)

What we want to happen in the DB:
select user_id from music_sys_tab; 
update music_sys_tab set user_id = user_id + 1;

Looking at InvoiceDAO, see separate method for this part, so here

int findNextUserId () {...}

insertUser, two ways

insertUser(User user) throws SQLException;
or insertUser(String firstName, String lastName, ...) throws SQLException;  

void insertUser(User user)throws SQLException;
--look at insertInvoice in InvoiceDAO

Need finder too

User findUser (String email) throws SQLException;

Service Layer: here have more app-specific names
UserService.java in package service

void registerUser(String firstName, String lastName, ...) throws ServiceException
call findUser, then insertUser if needed

Goal 3: SystemTest shows expected output (shouldn't show stub messages), and ant show-oradb shows new users

HTTP: read Chap. 18 to pg. 555.

Look at slides for Chap. 18.

Note error in book, pg. 549 : The « host » request header specifies the server name in request URL, i.e., the recipient’s hostname, not the sender’s hostname.

HTTP example of webpage with an image

MusicProjectUI.html  has:

 <img alt="music project page flow" src="MusicProjectUI_files/music_page_flow2.jpg"
        height="600px" width="750">

Browser accesses URL: http://www.cs.umb.edu, using 2 steps:

1. Connects to host www.cs.umb.edu on Port: 80 (default port for http)

2. Uses HTTP Command: GET /cs636/MusicProjectUI.html  HTTP/1.1 over that TCP connection, followed by header lines, then blank line to end

(as shown in Murach, pg. 545. Note that the blank line at the end for the GET doesn’t really show.)

Gets response:

Status line: HTTP/1.0 200 OK.
Response headers
blank line after headers
<Contents of index.html>

Then the connection is closed.

Browser parses the HTML

Finds <img….>

Browser reconnects to www.cs.umb.edu on port 80   (at least effectively, in fact this reconnect is optimized away.)

GET  /cs636/MusicProjectUI_files/music_page_flow2.jpg  HTTP/1.1
<headers>

Response:

HTTP/1.0 200 O.K
headers

<image data>

Browser display the image