/*
 * CatalogItem.java
 */

import java.sql.*;

/** A CatalogItem object represents one record in the 
 * catalog table. 
A record in the * catalog table is a description of a book. It does * not represent the physical existence of a book.
* (The inventory table contains records of the * actual books that have been acquired by the Library system.) * @author Timothy Paul Fox * @version August 09, 2004, 3:27 PM */ public class CatalogItem { private CatalogID catalogID; private String itemTitle; private String itemAuthor; private String itemPublisher; private String itemYear; private String ISBN; private String other; private String keyWords; private Statement userStmt; private Connection dbWire; private ResultSet rowRS; private boolean isNewRow; private String fieldInsertList; private String valueInsertList; private String updateList; private boolean titleChanged; private boolean authorChanged; private boolean publisherChanged; private boolean yearChanged; private boolean isbnChanged; private boolean otherChanged; private boolean keywordsChanged; { catalogID = null; itemTitle = itemAuthor = itemPublisher = itemYear = ISBN = other = keyWords = null; userStmt = null; dbWire = null; rowRS = null; isNewRow = false; resetAllChangeFlags(); } private void resetAllChangeFlags() { titleChanged = authorChanged = publisherChanged = yearChanged = isbnChanged = otherChanged = keywordsChanged = false; } // end resetAllChangeFlags private String quoteForSQL(String s) { StringBuffer sb = new StringBuffer(s); int qPos = -1; int lastQPos = 0; do { // escape any internal apostrophes // O'Reilly --> O''Reilly qPos = sb.indexOf("'", lastQPos); if (qPos >= 0) { sb.insert(qPos,'\''); lastQPos = qPos + 2; } } while (qPos >= 0); sb.insert(0, '\''); sb.append('\''); return sb.toString(); } // end quoteForSQL private void makeUpdateList(boolean changeAll) { int fieldCount = 0; StringBuffer sb = new StringBuffer(""); if ((itemTitle != null) && (changeAll || titleChanged)) { sb.append("title = " + quoteForSQL(itemTitle)); fieldCount++; } if ((itemAuthor != null) && (changeAll || authorChanged)) { if (fieldCount > 0) sb.append(", "); sb.append("author = " + quoteForSQL(itemAuthor) ); fieldCount++; } if ((itemPublisher != null) && (changeAll || publisherChanged)){ if (fieldCount > 0) sb.append(", "); sb.append("publisher = " + quoteForSQL(itemPublisher) ); fieldCount++; } if ((itemYear != null) && (changeAll || yearChanged)){ if (fieldCount > 0) { sb.append(", "); } sb.append("pub_year = " + quoteForSQL(itemYear) ); fieldCount++; } if ((ISBN != null) && (changeAll || isbnChanged)) { if (fieldCount > 0) sb.append(", "); sb.append("isbn = " + quoteForSQL(ISBN) ); fieldCount++; } if ((other != null) && (changeAll || otherChanged)) { if (fieldCount > 0) sb.append(", "); sb.append("other_key = " + quoteForSQL(other) ); fieldCount++; } if ((keyWords != null) && (changeAll || keywordsChanged)){ if (fieldCount > 0) sb.append(", "); sb.append("keywords = " + quoteForSQL(keyWords) ); fieldCount++; } updateList = sb.toString(); } // end makeUpdateList private void makeInsertLists() { StringBuffer fieldList = new StringBuffer("("); StringBuffer valueList = new StringBuffer("("); fieldList.append("catalog_id"); valueList.append(quoteForSQL(catalogID.toString())); fieldList.append(", "); valueList.append(", "); fieldList.append("title"); valueList.append(quoteForSQL(itemTitle)); fieldList.append(", "); valueList.append(", "); fieldList.append("author"); valueList.append(quoteForSQL(itemAuthor)); fieldList.append(", "); valueList.append(", "); fieldList.append("publisher"); valueList.append(quoteForSQL(itemPublisher)); fieldList.append(")"); valueList.append(")"); fieldInsertList = fieldList.toString(); valueInsertList = valueList.toString(); } // end makeInsertLists /** Creates a new instance of CatalogItem, and a record in the * catalog table. * The record created includes a new CatalogID. * @param title the title of the book (item) being added to the catalog. * Must be non-null and non-blank. Maximum storable length is * 55 characters. * @param author the author of the book. Must be non-null and non-blank. * Maximum storable length is 32 characters. * @param publisher the publisher of the book. Must be non-null and * non-blank. Maximum storable length is 20 characters. * @throws Exception generally SQLException from a JDBC access attempt, * also IllegalArgumentException for null or empty args */ public CatalogItem(String title, String author, String publisher) throws Exception { isNewRow = true; catalogID = new CatalogID(); if ((null == title) || (title.length() < 1)) throw new IllegalArgumentException( "CatalogItem(): Bad title arg"); if ((null == author) || (author.length() < 1)) throw new IllegalArgumentException( "CatalogItem(): Bad author arg"); if ((null == publisher) || (publisher.length() < 1)) throw new IllegalArgumentException( "CatalogItem(): Bad publisher arg"); itemTitle = title; itemAuthor = author; itemPublisher = publisher; makeInsertLists(); try { makeDbConnection("root"); // opens dbWire, userStmt int result = putToRow( "INSERT INTO catalog " + fieldInsertList + " VALUES " + valueInsertList ); if (result != 1) throw new SQLException( "CatalogItem:new record not written"); } finally { if (userStmt != null) userStmt.close(); if (dbWire != null) dbWire.close(); } } // end ContactInfo -- new record constructor /** writes any pending changes to the catalog * table. * @throws Exception whatever JDBC throws interacting with the database */ public void update() throws Exception { makeUpdateList(false); // make lists for changed fields only try { makeDbConnection("root"); // opens dbWire, userStmt int result = putToRow( "UPDATE catalog " + "SET " + updateList + " WHERE (catalog_id = " + quoteForSQL(catalogID.toString()) + ")"); if (result != 1) throw new SQLException( "CatalogItem:update() error"); resetAllChangeFlags(); } finally { if (userStmt != null) userStmt.close(); if (dbWire != null) dbWire.close(); } } // end update() /** Creates a CatalogItem object that represents a record that already * exists in the catalog table. * Finds a record in the catalog table whose * primary key matches knownID, then creates a CatalogItem object * and copies the record's data to it. * @param knownID the primary key (ItemID) in an * catalog record * @throws Exception from not contacting the database, * or not finding a matching record */ public CatalogItem(String knownID) throws Exception { catalogID = new CatalogID(knownID); try { makeDbConnection("root"); getFromRow("SELECT * from catalog " + "WHERE (catalog_id = " + quoteForSQL(catalogID.toString()) + ")"); rowRS.first(); itemTitle = rowRS.getString("title"); itemAuthor = rowRS.getString("author"); itemPublisher = rowRS.getString("publisher"); itemYear = rowRS.getString("pub_year"); ISBN = rowRS.getString("isbn"); other = rowRS.getString("other_key"); keyWords = rowRS.getString("keywords"); } finally { if (userStmt != null) userStmt.close(); if (dbWire != null) dbWire.close(); } } // end CatalogItem -- initializer to find existing record private void getFromRow(String query) throws Exception { rowRS = userStmt.executeQuery(query); } private void makeDbConnection(String user) throws Exception { LibManDbConnection plug; if (userStmt != null) userStmt.close(); if (dbWire != null) dbWire.close(); plug = new LibManDbConnection(user); dbWire = plug.connect(); userStmt = dbWire.createStatement(); } // end makeDbConnection private int putToRow(String updateSpec) throws Exception{ return userStmt.executeUpdate(updateSpec); } /** shows the contents of the CatalogItem object. * @return The output will be formatted as
* (title), (author), (publisher) (pubYear)
* (ISBN)
* (keywords)
* * NOTE: the (pubYear) (ISBN) and (keywords) data may be blank. */ public String toString() { StringBuffer sb = new StringBuffer("CatalogItem("); sb.append(catalogID.toString() + "): \n"); sb.append(getTitle() + ", "); sb.append(getAuthor() + ", "); sb.append(getPublisher() + " "); sb.append(getPubYear() + "\n"); sb.append(getISBN() + "\n"); sb.append(getKeywords() + "\n"); sb.append("\n"); return sb.toString(); } // end toString() /** gets the CatalogID * @return The primary key value for this item's record in the * catalog tables. */ public String getCatalogID() { return catalogID.toString(); } /** gets the title * @return the title of the book */ public String getTitle() { return (itemTitle == null)? "" : itemTitle; } /** gets the author name * @return the author of the book */ public String getAuthor() { return (itemAuthor == null)? "" : itemAuthor; } /** gets the publisher name * @return the publisher of the book */ public String getPublisher() { return (itemPublisher == null)? "" : itemPublisher; } /** gets the item's publication year * @return the year of publication, a four character string, if its * value has been set. Otherwise returns the empty string "". */ public String getPubYear() { return (itemYear == null)? "" : itemYear; } /** gets the item's ISBN * @return the ISBN if its value has been set. * Otherwise returns the empty string "". */ public String getISBN() { return ( ISBN == null)? "" : ISBN; } /** gets the item's 'other' key * @return the 'other' key if its value has been set. * Otherwise returns the empty string "". */ public String getOtherKey() { return (other == null)? "" : other; } /** gets the item's searchable key words * @return the words that indicate the genre or topic of the book, * if this property has been set. * Otherwise returns the empty string "". */ public String getKeywords() { return (keyWords == null)? "" : keyWords; } /** rewrites the title property of the item. Use this method to correct * mistakes in the item's title. * @param newS the title of the book. Must be non-blank * to be stored. Maximum storable length is 55 characters. * @param immediate If this is set true, the new * data will be written immediately to the database. * If false, the database will not be updated * until the update() method is called. * @throws Exception passes along whatever exception the update() * method encounters when trying to update the database. */ public void setTitle(String newS, boolean immediate) throws Exception { if (newS == null || newS.length() < 1) return; itemTitle = newS; titleChanged = true; if (immediate) update(); } /** rewrites the author property of the item. Use this method to * correct mistakes in the item's author name. * @param newS the name of the author the book. Must be * non-blank to be stored. Maximum storable length is 32 characters. * @param immediate If this is set true, the new * data will be written immediately to the database. * If false, the database will not be updated * until the update() method is called. * @throws Exception passes along whatever exception the update() * method encounters when trying to update the database. */ public void setAuthor(String newS, boolean immediate) throws Exception { if (newS == null || newS.length() < 1) return; itemAuthor = newS; authorChanged = true; if (immediate) update(); } /** rewrites the publisher property of the item. Use this method to * correct mistakes in the item's publisher name. * @param newS the name of the publisher the book. Must be * non-blank to be stored. Maximum storable length is 20 characters. * @param immediate If this is set true, the new * data will be written immediately to the database. * If false, the database will not be updated * until the update() method is called. * @throws Exception passes along whatever exception the update() * method encounters when trying to update the database. */ public void setPublisher(String newS, boolean immediate) throws Exception { if (newS == null || newS.length() < 1) return; itemPublisher = newS; publisherChanged = true; if (immediate) update(); } /** sets the publication year of the item. * @param newS the year the book was published. Must be * non-blank to be stored.
The parameter is not checked for * being a reasonable date value or format. Maximum storable length * is 4 characters. * @param immediate If this is set true, the new * data will be written immediately to the database. * If false, the database will not be updated * until the update() method is called. * @throws Exception passes along whatever exception the update() * method encounters when trying to update the database. */ public void setPubYear(String newS, boolean immediate) throws Exception { if (newS == null || newS.length() < 1) return; itemYear = newS; yearChanged = true; if (immediate) update(); } /** sets the ISBN property of the item. * @param newS the book's ISBN. Must be non-blank to be stored. *
The parameter is not checked for correctness * versus ISBN format specification. Maximum storable length is * 18 characters. * @param immediate If this is set true, the new * data will be written immediately to the database. * If false, the database will not be updated * until the update() method is called. * @throws Exception passes along whatever exception the update() * method encounters when trying to update the database. */ public void setISBN(String newS, boolean immediate) throws Exception { if (newS == null || newS.length() < 1) return; ISBN = newS; isbnChanged = true; if (immediate) update(); } /** sets the 'otherKey' property of the item. * @param newS the otherKey. Must be non-blank to be stored. * Maximum storable length is 8 characters. * @param immediate If this is set true, the new * data will be written immediately to the database. * If false, the database will not be updated * until the update() method is called. * @throws Exception passes along whatever exception the update() * method encounters when trying to update the database. */ public void setOtherKey(String newS, boolean immediate) throws Exception { if (newS == null || newS.length() < 1) return; other = newS; otherChanged = true; if (immediate) update(); } /** sets the 'keyWords' property of the item. * @param newS the keyWords. Must be non-blank to be stored. * Maximum storable length is 55 characters. * @param immediate If this is set true, the new * data will be written immediately to the database. * If false, the database will not be updated * until the update() method is called. * @throws Exception passes along whatever exception the update() * method encounters when trying to update the database. */ public void setKeywords(String newS, boolean immediate) throws Exception { if (newS == null || newS.length() < 1) return; keyWords = newS; keywordsChanged = true; if (immediate) update(); } } // end class CatalogItem