aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/net/cbaines/suca/CalendarApplet.java417
-rw-r--r--src/net/cbaines/suca/SotonCalendarFetcher.java37
-rw-r--r--src/net/cbaines/suca/SotonCalendarParser.java14
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);
}
}