import java.text.*;import java.util.*;import java.io.*;/****************************************************************The SimpleTime class keeps time in the hour/minute pair. It supportstime ordering comparison and the conversion to SimpleTime from Date orString.********************************************************************/class SimpleTime { private int hour, minute; private static final int MaxHour = 24, MaxMinute = 60; private static DecimalFormat fixedFormatter= new DecimalFormat("00"); private static Calendar calendar=GregorianCalendar.getInstance(); /** initiate SimpleTime object */ public SimpleTime(int hour, int minute) { setHour(hour); setMinute(minute); } /** get time from a Date object */ public SimpleTime(Date date) { calendar.setTime(date); hour=calendar.get(GregorianCalendar.HOUR_OF_DAY); minute=calendar.get(GregorianCalendar.MINUTE); } /** check if current time is strictly earlier than another time */ public boolean isEarlierThan(SimpleTime t) { return hour<t.hour || hour==t.hour && minute<t.minute ; } /** set hour */ public void setHour(int hr) { hour = hr % MaxHour; // max hour: 23:59 } /** set minute */ public void setMinute(int min) { minute = min % MaxMinute; } /** output time in xx:xx 24 hour format */ public String toString() { return fixedFormatter.format(hour)+":" + fixedFormatter.format(minute); } /** convert string to date, throws ParseException; format string takes the form of "hh:mma", "hha", "HH:mm", "HH" */ private static SimpleDateFormat getDateFormatter(String formatString) { SimpleDateFormat formatter = new SimpleDateFormat (formatString); formatter.setTimeZone(java.util.TimeZone.getDefault()); formatter.setLenient(false); return formatter; } /** convert string to SimpleTime */ public static SimpleTime stringToTime(String timeString) { String formats[]={"hh:mma" , "hha", "HH:mm", "HH"}; Date date=null; timeString = timeString.trim(); for (int i=0; date==null && i<formats.length; i++) { try { date=getDateFormatter(formats[i]).parse(timeString); } catch (Exception e) {} } return date==null? null: new SimpleTime(date); }}/****************************************************************The SimpleDate class keeps date in the day/month/year triplet. Itsupports date equality comparison and the conversion to SimpleDatefrom Date, text. Equality method is implemented so that 0 valuematches any day/month/year.********************************************************************/class SimpleDate { private int day,month,year; // month=1 : January private static Calendar calendar=GregorianCalendar.getInstance(); private static SimpleDateFormat formatter=new SimpleDateFormat("E"); /** initiate to default values 0/0/0 */ public SimpleDate() { day=month=year=0; } /** initiate SimpleDate object */ public SimpleDate(Date date) { calendar.setTime(date); day=calendar.get(GregorianCalendar.DAY_OF_MONTH); month=calendar.get(GregorianCalendar.MONTH)+1; year=calendar.get(GregorianCalendar.YEAR); } /** set day */ public void setDay(int d) { day=d; } /** set month */ public void setMonth(int m) { month=m; } /** set year */ public void setYear(int y) { year=y; } /** equalality: 0 is treated as a wild card */ public boolean equal(SimpleDate d) { return (day==0 || d.day==0 || day==d.day) && (month==0 || d.month==0 || month==d.month ) && (year==0 || d.year==0 || year==d.year ) ; } /** convert 7 days to characters: 'S', 'M', 'T', 'W', H', 'F', 'A' */ public static char dateToDay(Date date) { String day=formatter.format(date); day=day.toUpperCase(); if(day.indexOf("SAT")==0) return 'A'; else if(day.indexOf("THU")==0) return 'H'; else return day.charAt(0); } /** output day/month/year */ public String toString() { return day+"/"+month+"/"+year; } /** check if string consists of only legal chars "SMTWHFA" */ public static boolean isDay(String s) { for(int i=0; i<s.length();i++) { char ch=s.charAt(i); switch(ch) { case 'S': case 'M': case 'T': case 'W': case 'H': case 'F': case 'A': break; default: return false; } } return true; } /** convert string to date, throws ParseException; format string takes the form of "hh:mma", "hha", "HH:mm", "HH" */ public static SimpleDateFormat getDateFormatter(String formatString) { SimpleDateFormat formatter = new SimpleDateFormat (formatString); formatter.setTimeZone(java.util.TimeZone.getDefault()); formatter.setLenient(false); return formatter; } // duplicated in SimpleTime /** convert string to date, throws ParseException */ public static Date stringToDate(String dateString, String formatString) throws ParseException { return getDateFormatter(formatString).parse(dateString.trim()); } /** convert string of format d/M/yy to date */ public static Date stringToDate(String dateString) { Date date; try { date=stringToDate(dateString,"d/M/yy"); } catch (Exception e) { date=null; } return date; }}/****************************************************************The abstract Entry class is the base class of all entries.********************************************************************/abstract class Entry implements Comparable { // valid entry may have null values for startTime or endTime protected SimpleTime startTime,endTime; protected String dateOrDay,details; protected boolean validEntry=true; // not really needed /** check if current entry is valid */ public boolean isValid() { return validEntry; } /** fill common details */ protected void partialSetup(String dateOrDay, String startTime, String endTime, String details) { this.startTime=SimpleTime.stringToTime(startTime); this.endTime=SimpleTime.stringToTime(endTime); this.details=new String(details); this.dateOrDay=new String(dateOrDay); } /** html output: produce a table row */ public String toString() { return "\n<tr><td bgcolor=cyan>" + (startTime==null? "":startTime.toString()) + "-" + (endTime==null? "":endTime.toString()) + "</td>\n<td>" + details +"</td></tr>\n"; } /** to be implemented by Entry's subclasses */ public abstract boolean occursOn(Date date); public int compareTo(Object o) { return 1; }}/****************************************************************The EntryByDay class deals entries by day.********************************************************************/class EntryByDay extends Entry { private String d; /** create an entry head by days */ public EntryByDay(String days, String startTime, String endTime, String details) { d=new String(days); partialSetup(days,startTime,endTime,details); } /** implement its special occursOn() */ public boolean occursOn(Date date) { char day=SimpleDate.dateToDay(date); if(!validEntry) return false; return d.indexOf(day)!= -1; }}/****************************************************************The EntryByDate class deals entries by dates.STUDENT WORK TYPICALLY NEEDED HERE.********************************************************************/class EntryByDate extends Entry { private SimpleDate d; public EntryByDate(String days, String startTime, String endTime, String details) { d = new SimpleDate(); if (days.indexOf('/') != -1) { String[] b = days.split("/"); if (b.length > 2) { if (Integer.parseInt(b[2]) == 0) d.setDay(Integer.parseInt(b[2])); else d.setDay(Integer.parseInt("20"+b[2])); } else { d.setDay(Integer.parseInt(b[0])); d.setMonth(Integer.parseInt(b[1])); d.setYear(0); } } else { d.setDay(Integer.parseInt(days)); d.setMonth(0); d.setYear(0); } partialSetup(days, startTime, endTime, details); } public boolean occursOn(Date date) { if (!validEntry) return false; SimpleDate other = new SimpleDate(date); return d.equal(other); }}/****************************************************************Schedule is the main class. It may read from stdin to create a list ofentries, and select entries based on any given date. STUDENT WORK TYPICALLY NEEDED HERE.********************************************************************/class Schedule { private ArrayList entries; private String eventfile; /** initiate an empty list of entries */ public Schedule(String file) { entries=new ArrayList(); eventfile = file; } /** add an entry to the schedule */ public void add(Entry e) { entries.add(e); } /** add an entry in the form of strings */ public void add(String dateOrDay, String startTime, String endTime, String details ) { SimpleDate a = new SimpleDate(); if (a.isDay(dateOrDay)) entries.add(new EntryByDay(dateOrDay,startTime,endTime,details)); else entries.add(new EntryByDate(dateOrDay, startTime, endTime, details)); } /** add an event which is in the form of a single line */ public void add(String line) { String start, finish; StringTokenizer data = new StringTokenizer(line); String date = data.nextToken(); String time = data.nextToken(); String desc = data.nextToken("#").trim(); String[] b = time.trim().split("-"); // Time handler if (time.charAt(0) == '-') { start = "0:00"; if (time.length() == 1) finish = "23:59"; else finish = b[1]; } else { start = b[0]; if (time.charAt(time.length()-1) == '-') finish = "23:59"; else if (b.length == 1) finish = "23:59"; else finish = b[1]; } add(date, start, finish, desc); } /** read all entries from a file */ public void read() { String line; try { BufferedReader reader= new BufferedReader(new FileReader(eventfile)); while(true) { line=reader.readLine().trim(); if(line.length()==0 || line.charAt(0)=='#') continue; add(line); } } catch(Exception e) {} } /** write schedule to standard output stream */ public void write() { for(int i=0;i<entries.size();i++) System.out.print((Entry) entries.get(i)); } /** create a new subschedule containing all entries happening on a date */ public Schedule occursOn(Date date) { Schedule dailyEntries=new Schedule(eventfile); for(int i=0;i<entries.size();i++) { Entry entry =(Entry) entries.get(i); if(entry.isValid() && entry.occursOn(date)) dailyEntries.add(entry); } return dailyEntries; } /** create a schedule from stdin */ public void getSchedule(String[] args) { Schedule subEntries; SimpleDate e = new SimpleDate(); Date date; int days = (args.length > 2 ? Integer.valueOf(args[2]).intValue() : 1); if (args.length > 1) date = e.stringToDate(args[1]); else date = new Date(); // reading and parsing events read(); // output entries in html format System.out.print("<html><body bgcolor=white>\n\n" + "<h1>Scheduled Entries</h1>\n\n" + "<table border=2 cellspacing=0 cellpadding=3 bgcolor=yellow>\n"); for (int i=0; i<days;i++) { System.out.print("\n<tr><td align=center colspan=2 bgcolor=red><b><font size=+1 color=white> " + SimpleDate.getDateFormatter("E d/M/yyyy").format(date) + " </font></b></td></tr>\n"); subEntries=occursOn(date); Collections.sort(subEntries); subEntries.write(); date.setDate(date.getDate()+1); } System.out.print("\n</table>\n\n"); System.out.println("</body></html>"); } /** the program entry point */ public static void main(String[] args) { Schedule d = new Schedule(args[0]); d.getSchedule(args); }}