diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/net/cbaines/suca/CalendarApplet.java | 417 | ||||
-rw-r--r-- | src/net/cbaines/suca/SotonCalendarFetcher.java | 37 | ||||
-rw-r--r-- | src/net/cbaines/suca/SotonCalendarParser.java | 14 |
3 files changed, 308 insertions, 160 deletions
diff --git a/src/net/cbaines/suca/CalendarApplet.java b/src/net/cbaines/suca/CalendarApplet.java index 816084f..c94c6f4 100644 --- a/src/net/cbaines/suca/CalendarApplet.java +++ b/src/net/cbaines/suca/CalendarApplet.java @@ -1,14 +1,16 @@ package net.cbaines.suca; import java.awt.Container; -import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedWriter; import java.io.File; +import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.io.Reader; import java.io.StringReader; +import java.lang.reflect.InvocationTargetException; import javax.security.auth.login.LoginException; import javax.swing.BorderFactory; @@ -22,7 +24,11 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JProgressBar; +import javax.swing.JTabbedPane; import javax.swing.JTextField; +import javax.swing.SwingUtilities; + +import org.apache.commons.io.IOUtils; import net.fortuna.ical4j.data.CalendarBuilder; import net.fortuna.ical4j.data.ParserException; @@ -44,6 +50,8 @@ public class CalendarApplet extends JApplet { private JButton fetchCalendarButton; private JProgressBar fetchCalendarProgress; + private JButton uploadCSVButton; + // iCal Calendar Creation Options private JPanel calendarCreationOptions; @@ -60,188 +68,321 @@ public class CalendarApplet extends JApplet { // Data private volatile String calendarCSVString = null; - private volatile String calendarICALString = null; + + private volatile Calendar calendar = null; + + private final SotonCalendarParser calParser = new SotonCalendarParser(); public void init() { - // Execute a job on the event-dispatching thread: - // creating this applet's GUI. try { - javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + SwingUtilities.invokeAndWait(new Runnable() { public void run() { - createGUI(); - } - }); - } catch (Exception e) { - System.err.println("createGUI didn't successfully complete"); - } - } + try { + stages = getContentPane(); + stages.setLayout(new BoxLayout(stages, BoxLayout.PAGE_AXIS)); - void createGUI() { - try { + // Load University Calendar Stage - stages = getContentPane(); - stages.setLayout(new BoxLayout(stages, BoxLayout.PAGE_AXIS)); + calendarLoadingPanel = new JPanel(); + calendarLoadingPanel.setBorder(BorderFactory.createTitledBorder("Load University Calendar")); - // Load University Calendar Stage + JTabbedPane calendarLoadingChoiceTabbedPane = new JTabbedPane(); - calendarLoadingPanel = new JPanel(); - calendarLoadingPanel.setBorder(BorderFactory.createTitledBorder("Load University Calendar")); + JPanel downloadPanel = new JPanel(); - JPanel usernamePanel = new JPanel(); - usernamePanel.add(new JLabel("Username")); - usernameTextField = new JTextField(10); - usernamePanel.add(usernameTextField); - calendarLoadingPanel.add(usernamePanel); + JPanel usernamePanel = new JPanel(); + usernamePanel.add(new JLabel("Username")); + usernameTextField = new JTextField(10); + usernamePanel.add(usernameTextField); + downloadPanel.add(usernamePanel); + + JPanel passwordPanel = new JPanel(); + passwordPanel.add(new JLabel("Password")); + passwordTextField = new JPasswordField(10); + passwordPanel.add(passwordTextField); + downloadPanel.add(passwordPanel); + + fetchCalendarButton = new JButton("Fetch Calendar"); + fetchCalendarButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + fetchCalendarButton.setEnabled(false); + fetchCalendarProgress.setIndeterminate(true); + fetchCalendarProgress.setValue(0); + new Thread(new DownloadCSV()).start(); + } + }); + downloadPanel.add(fetchCalendarButton); - JPanel passwordPanel = new JPanel(); - passwordPanel.add(new JLabel("Password")); - passwordTextField = new JPasswordField(10); - passwordPanel.add(passwordTextField); - calendarLoadingPanel.add(passwordPanel); + calendarLoadingChoiceTabbedPane.addTab("Download Calendar", downloadPanel); - fetchCalendarButton = new JButton("Fetch Calendar"); - fetchCalendarButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - new FetchThread().start(); - } - }); - calendarLoadingPanel.add(fetchCalendarButton); + JPanel uploadPanel = new JPanel(); - fetchCalendarProgress = new JProgressBar(); - fetchCalendarProgress.setIndeterminate(false); - fetchCalendarProgress.setValue(0); - calendarLoadingPanel.add(fetchCalendarProgress); + uploadCSVButton = new JButton("Upload CSV"); + uploadCSVButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + JFileChooser fc = new JFileChooser(); + int returnVal = fc.showOpenDialog(instance); // this = Applet + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = fc.getSelectedFile(); - stages.add(calendarLoadingPanel); + try { + new Thread(new UploadCSV(IOUtils.toString(new FileReader(file)))).start(); + } catch (IOException e) { + e.printStackTrace(); + } - // iCal Calendar Creation Options + } - calendarCreationOptions = new JPanel(); - calendarCreationOptions.setBorder(BorderFactory.createTitledBorder("Calendar Options")); + } + }); - calendarCreationOptions.add(mergeDuplicateEventsWithSeperateLocations); - calendarCreationOptions.add(showTerms); - calendarCreationOptions.add(showSemesters); - calendarCreationOptions.add(showSemesterWeeks); - calendarCreationOptions.add(mergeHeaders); + uploadPanel.add(uploadCSVButton); - stages.add(calendarCreationOptions); + calendarLoadingChoiceTabbedPane.addTab("Upload Calendar", uploadPanel); - // Calendar Download + calendarLoadingPanel.add(calendarLoadingChoiceTabbedPane); - downloadCalendarPanel = new JPanel(); - downloadCalendarPanel.setBorder(BorderFactory.createTitledBorder("Download Calendar (iCal)")); + fetchCalendarProgress = new JProgressBar(); + fetchCalendarProgress.setIndeterminate(false); + fetchCalendarProgress.setValue(0); + calendarLoadingPanel.add(fetchCalendarProgress); - donwloadCalendarButton = new JButton("Download Calendar"); - donwloadCalendarButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - CreationThread creationThread = new CreationThread(); - creationThread.start(); + stages.add(calendarLoadingPanel); - JFileChooser fc = new JFileChooser(); - int returnVal = fc.showSaveDialog(instance); // this = Applet - if (returnVal == JFileChooser.APPROVE_OPTION) { - File file = fc.getSelectedFile(); - try { - creationThread.join(); - } catch (InterruptedException e1) { - e1.printStackTrace(); - } + // iCal Calendar Creation Options - try { - BufferedWriter out = new BufferedWriter(new FileWriter(file)); - out.write(calendarICALString); - out.flush(); - out.close(); - } catch (IOException e) { - e.printStackTrace(); - } + calendarCreationOptions = new JPanel(); + calendarCreationOptions.setBorder(BorderFactory.createTitledBorder("Calendar Options")); - } + calendarCreationOptions.add(mergeDuplicateEventsWithSeperateLocations); + calendarCreationOptions.add(showTerms); + calendarCreationOptions.add(showSemesters); + calendarCreationOptions.add(showSemesterWeeks); + calendarCreationOptions.add(mergeHeaders); - } - }); - downloadCalendarPanel.add(donwloadCalendarButton); + setStageTwo(false); + + stages.add(calendarCreationOptions); - stages.add(downloadCalendarPanel); + // Calendar Download - } catch (Exception e) { + downloadCalendarPanel = new JPanel(); + downloadCalendarPanel.setBorder(BorderFactory.createTitledBorder("Download Calendar (iCal)")); + + donwloadCalendarButton = new JButton("Download Calendar"); + donwloadCalendarButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + Thread creationThread = new Thread(new CreateCalendar()); + creationThread.start(); + + JFileChooser fc = new JFileChooser(); + int returnVal = fc.showSaveDialog(instance); // this = Applet + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = fc.getSelectedFile(); + try { + creationThread.join(); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + + try { + BufferedWriter out = new BufferedWriter(new FileWriter(file)); + out.write(calendar.toString()); + out.flush(); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + } + }); + downloadCalendarPanel.add(donwloadCalendarButton); + + setStageThree(false); + + stages.add(downloadCalendarPanel); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (InterruptedException e) { e.printStackTrace(); } } - private class FetchThread extends Thread { + private void setStageTwo(boolean enable) { + calendarCreationOptions.setEnabled(enable); + + mergeDuplicateEventsWithSeperateLocations.setEnabled(enable); + showTerms.setEnabled(enable); + showSemesters.setEnabled(enable); + showSemesterWeeks.setEnabled(enable); + mergeHeaders.setEnabled(enable); + } + + private void setStageThree(boolean enable) { + downloadCalendarPanel.setEnabled(enable); + + donwloadCalendarButton.setEnabled(enable); + } + + private class UploadCSV implements Runnable { + private String csvString; - public FetchThread() { - super(); + UploadCSV(String csvString) { + this.csvString = csvString; } @Override public void run() { - System.out.println("Start of fetch thread"); - fetchCalendarButton.setEnabled(false); - fetchCalendarProgress.setIndeterminate(true); - fetchCalendarProgress.setValue(0); - - String csvString; try { - csvString = new SotonCalendarFetcher(usernameTextField.getText(), String.valueOf(passwordTextField - .getPassword())).fetchAndParseTimetable(); - - System.out.println("Finished fetch"); + createCalendar(csvString); calendarCSVString = csvString; - System.out.println("Finished fetch thread"); - - fetchCalendarButton.setEnabled(true); - fetchCalendarProgress.setIndeterminate(false); - fetchCalendarProgress.setValue(100); - - } catch (LoginException e) { - fetchCalendarButton.setEnabled(true); - fetchCalendarProgress.setIndeterminate(false); - fetchCalendarProgress.setValue(0); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + fetchCalendarButton.setEnabled(true); + fetchCalendarProgress.setIndeterminate(false); + fetchCalendarProgress.setValue(100); - JOptionPane.showMessageDialog(instance, - "LoginException: Error logging in, try again, and perhaps also try logging in to SUSSED", - "Inane error", JOptionPane.ERROR_MESSAGE); + setStageTwo(true); + setStageThree(true); + } + }); } catch (IOException e) { - fetchCalendarButton.setEnabled(true); - fetchCalendarProgress.setIndeterminate(false); - fetchCalendarProgress.setValue(0); - - JOptionPane.showMessageDialog(instance, - "IOException: Error logging in, try again, and perhaps also try logging in to SUSSED", - "Inane error", JOptionPane.ERROR_MESSAGE); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + fetchCalendarButton.setEnabled(true); + fetchCalendarProgress.setIndeterminate(false); + fetchCalendarProgress.setValue(0); + + JOptionPane.showMessageDialog(instance, "IOException: Error loading csv file", "Inane error", + JOptionPane.ERROR_MESSAGE); + } + }); + } catch (ParserException e) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + fetchCalendarButton.setEnabled(true); + fetchCalendarProgress.setIndeterminate(false); + fetchCalendarProgress.setValue(0); + + JOptionPane.showMessageDialog(instance, "ParserException: Error parsing csv", "Inane error", + JOptionPane.ERROR_MESSAGE); + } + }); } } } - private class CreationThread extends Thread { - - public CreationThread() { - super(); - } + private class DownloadCSV implements Runnable { @Override public void run() { - System.out.println("Starting creation thread"); + try { + // Fetch + String csvString = new SotonCalendarFetcher(usernameTextField.getText(), + passwordTextField.getPassword()).fetchAndParseTimetable(); + + if (csvString == null) { + System.err.println("Got a null string back from SotonCalendarFetcher"); + } + + try { + createCalendar(csvString); - SotonCalendarParser calParser = new SotonCalendarParser(); - calParser.setMergeDuplicateEventsWithSeperateLocations(mergeDuplicateEventsWithSeperateLocations - .isSelected()); - calParser.setMergeHeaders(mergeHeaders.isSelected()); - calParser.setShowSemesters(showSemesters.isSelected()); - calParser.setShowSemesterWeeks(showSemesterWeeks.isSelected()); - calParser.setShowTerms(showTerms.isSelected()); + calendarCSVString = csvString; - CalendarBuilder builder = new CalendarBuilder(calParser); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + fetchCalendarButton.setEnabled(true); + fetchCalendarProgress.setIndeterminate(false); + fetchCalendarProgress.setValue(100); + + setStageTwo(true); + setStageThree(true); + } + }); + } catch (ParserException e) { + e.printStackTrace(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + fetchCalendarButton.setEnabled(true); + fetchCalendarProgress.setIndeterminate(false); + fetchCalendarProgress.setValue(0); + + JOptionPane.showMessageDialog(instance, "ParserException: Error parsing the csv file", + "Inane error", JOptionPane.ERROR_MESSAGE); + } + }); + } catch (IOException e) { + e.printStackTrace(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + fetchCalendarButton.setEnabled(true); + fetchCalendarProgress.setIndeterminate(false); + fetchCalendarProgress.setValue(0); + + JOptionPane.showMessageDialog(instance, "IOException: IO Exception when reading the csv?", + "Inane error", JOptionPane.ERROR_MESSAGE); + } + }); + } + } catch (LoginException e) { + e.printStackTrace(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + fetchCalendarButton.setEnabled(true); + fetchCalendarProgress.setIndeterminate(false); + fetchCalendarProgress.setValue(0); + + JOptionPane + .showMessageDialog( + instance, + "LoginException: Error logging in, try again, and perhaps also try logging in to SUSSED", + "Inane error", JOptionPane.ERROR_MESSAGE); + } + }); + } catch (IOException e) { + e.printStackTrace(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + fetchCalendarButton.setEnabled(true); + fetchCalendarProgress.setIndeterminate(false); + fetchCalendarProgress.setValue(0); + + JOptionPane.showMessageDialog(instance, + "IOException: Error logging in, try again, and perhaps also try logging in to SUSSED", + "Inane error", JOptionPane.ERROR_MESSAGE); + } + }); + } + } + } + + private class CreateCalendar implements Runnable { + + @Override + public void run() { try { - Calendar calendar = builder.build(new StringReader(calendarCSVString)); - calendarICALString = calendar.toString(); + calendar = createCalendar(calendarCSVString); } catch (ParserException e) { e.printStackTrace(); } catch (IOException e) { @@ -251,4 +392,16 @@ public class CalendarApplet extends JApplet { } } + private Calendar createCalendar(String csvString) throws IOException, ParserException { + calParser.setMergeDuplicateEventsWithSeperateLocations(mergeDuplicateEventsWithSeperateLocations.isSelected()); + calParser.setMergeHeaders(mergeHeaders.isSelected()); + calParser.setShowSemesters(showSemesters.isSelected()); + calParser.setShowSemesterWeeks(showSemesterWeeks.isSelected()); + calParser.setShowTerms(showTerms.isSelected()); + + CalendarBuilder builder = new CalendarBuilder(calParser); + + return builder.build(new StringReader(csvString)); + } + } diff --git a/src/net/cbaines/suca/SotonCalendarFetcher.java b/src/net/cbaines/suca/SotonCalendarFetcher.java index 846faf1..370bf33 100644 --- a/src/net/cbaines/suca/SotonCalendarFetcher.java +++ b/src/net/cbaines/suca/SotonCalendarFetcher.java @@ -23,17 +23,23 @@ import org.apache.http.protocol.HTTP; public class SotonCalendarFetcher { private String username; - private String password; + private char[] password; - public SotonCalendarFetcher(String username, String password) { + public SotonCalendarFetcher(String username, char[] password) { this.username = username; this.password = password; + // for (int i = 0; i < password.length; i++) { + // password[i] = 0; + // } } @SuppressWarnings("deprecation") public String fetchAndParseTimetable() throws IOException, LoginException { + if (username == null) { + throw new RuntimeException("Username null, or method called more than once."); + } + DefaultHttpClient httpclient = new DefaultHttpClient(); - Exception exception = null; try { HttpGet httpget = new HttpGet("https://www.adminservices.soton.ac.uk/adminweb/servlet/login"); @@ -61,9 +67,13 @@ public class SotonCalendarFetcher { HttpPost httpost = new HttpPost("https://www.adminservices.soton.ac.uk/adminweb/servlet/login"); List<NameValuePair> nvps = new ArrayList<NameValuePair>(); + System.out.println(username + " " + String.valueOf(password)); nvps.add(new BasicNameValuePair("user", username)); - nvps.add(new BasicNameValuePair("pwd", password)); - System.out.println(username + password); + nvps.add(new BasicNameValuePair("pwd", String.valueOf(password))); + for (int i = 0; i < password.length; i++) { + password[i] = 0; + } + username = null; httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); @@ -162,22 +172,13 @@ public class SotonCalendarFetcher { return responseString; } catch (IOException e) { - exception = e; + httpclient.getConnectionManager().shutdown(); + throw e; } catch (LoginException e) { - exception = e; + httpclient.getConnectionManager().shutdown(); + throw e; } finally { - if (exception != null) { - if (exception instanceof IOException) { - throw (IOException) exception; - } else if (exception instanceof IOException) { - throw (LoginException) exception; - } - } - // When HttpClient instance is no longer needed, - // shut down the connection manager to ensure - // immediate deallocation of all system resources httpclient.getConnectionManager().shutdown(); } - return null; } } diff --git a/src/net/cbaines/suca/SotonCalendarParser.java b/src/net/cbaines/suca/SotonCalendarParser.java index 38b6ac2..7734dc5 100644 --- a/src/net/cbaines/suca/SotonCalendarParser.java +++ b/src/net/cbaines/suca/SotonCalendarParser.java @@ -5,7 +5,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; -import java.net.URISyntaxException; import java.text.ParseException; import java.util.ArrayList; import java.util.Calendar; @@ -58,10 +57,9 @@ public class SotonCalendarParser implements CalendarParser { * * @param in * @param handler - * @throws IOException - * @throws ParserException + * @throws ParseException */ - public void parse(BufferedReader in, ContentHandler handler) throws IOException, ParserException { + public void parse(BufferedReader in, ContentHandler handler) throws ParserException { try { log("Year " + Calendar.getInstance().get(Calendar.YEAR)); int currentYear = Calendar.getInstance().get(Calendar.YEAR); @@ -72,7 +70,6 @@ public class SotonCalendarParser implements CalendarParser { handler.endProperty(Property.NAME); handler.startProperty(Property.VERSION); handler.propertyValue("2.0"); - handler.endProperty(Property.VERSION); handler.startProperty(Property.PRODID); handler.propertyValue("-//Chris Baines + Henco Appel//SouthamptonUniversityOrganiser//EN"); handler.endProperty(Property.NAME); @@ -524,12 +521,9 @@ public class SotonCalendarParser implements CalendarParser { } handler.endCalendar(); - } catch (ParseException e) { - e.printStackTrace(); - } catch (URISyntaxException e) { - e.printStackTrace(); - } catch (NumberFormatException e) { + } catch (Exception e) { e.printStackTrace(); + throw new ParserException("Error parsing csv", 0); } } |