import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.TreeMap; import processing.core.PApplet; /* * Pehr Hovey * MAT259 Project 1 Winter 2009 * * Graph Checkout duration, collection code and time in 2D * * TransactionUtils.java - represent one library transaction. * Store only fields needed for this visualization * * Based on course code from Angus * */ public class TransactionUtils { //sort a List of transactions by the title public static void sortTransactionsByTitle(ArrayList transactions) { Collections.sort(transactions, new Comparator() { public int compare(Object o1, Object o2) { Transaction t1 = (Transaction) o1; Transaction t2 = (Transaction) o2; return t1.title.compareToIgnoreCase(t2.title); } } ); } public static void sortTransactionsByCheckinTimeStamp(ArrayList transactions) { Collections.sort(transactions, new Comparator() { public int compare(Object o1, Object o2) { Transaction t1 = (Transaction) o1; Transaction t2 = (Transaction) o2; Long l1 = new Long(t1.ckitimestamp); Long l2 = new Long(t2.ckitimestamp); return l1.compareTo(l2); } } ); } //Iterate through array and tally up cumulative checkin, checkout counts //This is designed to be run on a mixed array of checkins and checkouts, sorted by time. public static void calculateCumulativeValuesAndMidPts(ArrayList transactions, ArrayList midpoints){ Iterator itr = transactions.iterator(); Transaction t; long checkins=0,checkouts=0; while(itr.hasNext()){ t = (Transaction) itr.next(); if(t.is_checkin) checkins++; else checkouts++; t.cumulative_checkins=checkins; t.cumulative_checkouts=checkouts; midpoints.add(new Double((double)checkins / (checkins+checkouts))); //store the cumulative percentage } } //If this is a checkin, sort by checkin-time. if it is a checkout, sort by checkout time. //Note that checkouts don't have a checkin timestamp public static void sortTransactionsByNaturalTimeStamp(ArrayList transactions) { Collections.sort(transactions, new Comparator() { public int compare(Object o1, Object o2) { //figure out which timestamp represents each object in the sort Transaction t1 = (Transaction) o1; Transaction t2 = (Transaction) o2; Long l1,l2; if(t1.is_checkin) l1 = new Long(t1.ckitimestamp); else l1 = new Long(t1.ckotimestamp); if(t2.is_checkin) l2 = new Long(t2.ckitimestamp); else l2 = new Long(t2.ckotimestamp); return l1.compareTo(l2); } } ); } public static void sortTransactionsByDuration(ArrayList transactions) { Collections.sort(transactions, new Comparator() { public int compare(Object o1, Object o2) { Transaction t1 = (Transaction) o1; Transaction t2 = (Transaction) o2; Long l1 = new Long(t1.ckoduration); Long l2 = new Long(t2.ckoduration); return l1.compareTo(l2); } } ); } public static void sortTransactionsBySection(ArrayList transactions) { Collections.sort(transactions, new Comparator() { public int compare(Object o1, Object o2) { Transaction t1 = (Transaction) o1; Transaction t2 = (Transaction) o2; String s1 = getSection(t1.collcode); String s2 = getSection(t2.collcode); return s1.compareToIgnoreCase(s2); } } ); } public static void sortTransactionsByItemType(ArrayList transactions) { Collections.sort(transactions, new Comparator() { public int compare(Object o1, Object o2) { Transaction t1 = (Transaction) o1; Transaction t2 = (Transaction) o2; String s1 = getItemType(t1.itemtype); String s2 = getItemType(t2.itemtype); return s1.compareToIgnoreCase(s2); } } ); } public static void sortTransactionsByCollection(ArrayList transactions) { Collections.sort(transactions, new Comparator() { public int compare(Object o1, Object o2) { Transaction t1 = (Transaction) o1; Transaction t2 = (Transaction) o2; String s1 = getCollection(t1.collcode); String s2 = getCollection(t2.collcode); return s1.compareToIgnoreCase(s2); } } ); } //reverse order of List public static void reverse(ArrayList transactions) { Collections.reverse(transactions); } public static void filterOutNonAlphabeticalTitles(ArrayList transactions) { for (int i = transactions.size() - 1; i >= 0; i--) { Transaction t = (Transaction) transactions.get(i); if (t.title.length() < 1) { transactions.remove(t); continue; } char firstLetter = t.title.charAt(0); if (! ((firstLetter >= 'a' && firstLetter <= 'z') || (firstLetter >= 'A' && firstLetter <= 'Z')) ) { transactions.remove(t); continue; } } } // create a new transaction obejct from a comma separated line. public static Transaction parseTransaction(String line) { String sections[] = PApplet.split(line, ","); Transaction t = new Transaction(); //store all fields t.itemNumber = sections[0]; t.ckodate = sections[1]; t.ckotime = sections[2]; t.ckidate = sections[3]; t.ckitime = sections[4]; t.collcode = sections[5]; t.itemtype = sections[6]; if(sections.length > 7){ //some transactions don't have a title! t.title = sections[7]; }else{ System.err.println("no title for item#"+t.itemNumber); } t.calculateDuration(); t.calculateTimeStamps(); return t; } //This method has been redone to also take an array that specifies which column of data is which field. // This way we can easily change the order or # of data columns in // XML_Stripper and not have to also change it here... public static Transaction parseTransaction(String[] fields, String line) { String sections[] = PApplet.split(line, ","); // assert (sections.length == fields.length); //Assertions not supported // in java 1.4 Transaction t = new Transaction(); for (int f = 0; f < fields.length; f++) { String field = fields[f]; String val = sections[f]; if (field.equals("ckodate")) { t.ckodate = val; } else if (field.equals("ckidate")) { t.ckidate = val; } else if (field.equals("itemNumber")) { t.itemNumber = val; } else if (field.equals("ckotime")) { t.ckotime = val; } else if (field.equals("ckitime")) { t.ckitime = val; } else if (field.equals("collcode")) { t.collcode = val; } else if (field.equals("itemtype")) { t.itemtype = val; } else if (field.equals("title")) { t.title = val; } else if (field.equals("deweyClass")) { t.deweyClass = val; } else if (field.equals("callNumber")) { t.callNumber = val; } // // System.out.println("setting "+field+" => "+val); } // System.out.println(t.toString()); return t; } // Strip surrounding codes from collcode to get if its childrens, young // adult, etc public static String getSection(String collcode){ //First char is book home, 2nd char is what we want. everything else afterwards is variable length return collcode.substring(1,2); } public static String getCollection(String collcode){ //First char is book home, 2nd char is section. everything else afterwards is collection return collcode.substring(2); } public static String getItemType(String itemtype){ //First char controls fine-policy, second char is whether it can be checked out, all following is itemtype return itemtype.substring(2); } //Given two already assembled Gregorian Calendar dates, calc time diff in milliseconds public static long getTimeDifferenceInMillis(java.util.GregorianCalendar gc1, java.util.GregorianCalendar gc2) { return gc2.getTimeInMillis() - gc1.getTimeInMillis(); } //Take date/time in a string format and return greg. cal. public static java.util.GregorianCalendar getGCFromString(String date, String time){ // GregorianCalendar(int year, int month, int dayOfMonth, int hourOfDay, int minute, int second) //Date, time string format: 2008-05-02 10:43:00 // System.out.println("Parsing d/t: "+date+" / "+time); int year = Integer.valueOf(date.substring(0, 4)).intValue(); int month = Integer.valueOf(date.substring(5,7)).intValue(); int dayOfMonth = Integer.valueOf(date.substring(8,10)).intValue(); int hourOfDay = Integer.valueOf(time.substring(0,2)).intValue(); int minute = Integer.valueOf(time.substring(3,5)).intValue(); int second = Integer.valueOf(time.substring(6,8)).intValue(); // System.out.println(year+" "+month+" "+dayOfMonth+' '+hourOfDay+' '+minute+' '+second); java.util.GregorianCalendar gc = new java.util.GregorianCalendar(year, month-1, dayOfMonth, hourOfDay,minute,second); // System.out.println(gc.getTime()); return gc; } // //Make a deep copy of an ArrayList of transactions //deep copy means all the objects inside are new instances so modifying the source //will not affect the destination public static ArrayList copyTransactions(ArrayList source){ ArrayList dest = new ArrayList(source.size()); for(int i=0; i< source.size(); i++){ dest.add(i,new Transaction((Transaction)source.get(i))); //put it in the same place } return dest; } }