package io; import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.util.HashSet; import java.util.Scanner; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import org.json.JSONException; import org.json.JSONObject; import provider.ResultListener; /** * This class writes the output data into seperate files. * * @author Maurice Laveaux */ public class DataWriter implements ResultListener { /** * The writer for the tweet stream. */ private final FileWriter m_tweetWriter; /** * the writer for the profile stream. */ private final FileWriter m_profileWriter; /** * the buffer of tweet ids that already exist. */ private final Set m_tweetIdSet; /** * the buffer of profile ids that already exist. */ private final Set m_profileIdSet; public final static String CFG_PROFILE_FILENAME = "profiles-filename"; public final static String CFG_TWEETS_FILENAME = "tweets-filename"; /** * Opens a stream to every single file that data will be streamed to. * @param profilesName The file to write the profiles to. * @param tweetsName The file to write the tweets to. */ public DataWriter(final String profilesName, final String tweetsName) { try { m_profileIdSet = readIds(profilesName); m_profileWriter = new FileWriter(profilesName, true); m_tweetIdSet = readIds(tweetsName); m_tweetWriter = new FileWriter(tweetsName, true); } catch (IOException ex) { // This should not happen. throw new RuntimeException(ex.getMessage()); } } public void close() { try { m_tweetWriter.close(); m_profileWriter.close(); } catch (IOException ex) { getLogger().log(Level.SEVERE, null, ex); } } @Override public void profileGenerated(JSONObject obj) { writeObject(obj, m_profileWriter, m_profileIdSet); } @Override public void tweetGenerated(JSONObject obj) { writeObject(obj, m_tweetWriter, m_tweetIdSet); } /** * Read the current existing tweetName and profileName filenames and fill * the existing id set, it will create the file when it doesn't exist. * * @param filename The file to parse * @return The set of ids */ private Set readIds(String filename) throws IOException { try { Scanner reader = new Scanner(new File(filename)); // TODO: Read the file JSON objects and parse the ids. Set idSet = new HashSet(); // parse each line into a JSONObject, read the id and add it to // the set of ids. while (reader.hasNext()) { JSONObject obj = new JSONObject(reader.nextLine()); long id = obj.getLong("id"); idSet.add(id); } return idSet; } catch (FileNotFoundException ex) { // File does not exist, so create one. File file = new File(filename); // Return value should always be true. file.createNewFile(); } catch (JSONException ex) { getLogger().log(Level.SEVERE, null, ex); } // return the empty set. return new HashSet(); } /** * Writes the JSONObject to a writer and update the idSet. * * @param obj The object to write. * @param writer The writer object to append the object to. * @param idSet The id set to add the obj id to. */ private void writeObject(JSONObject obj, FileWriter writer, Set idSet) { try { long id = obj.getLong("id"); if (!idSet.contains(id)) { // Write a single profile into the profile file. try { writer.write(obj.toString() + "\n"); idSet.add(id); } catch (IOException ex) { getLogger().log(Level.SEVERE, null, ex); } } } catch (JSONException ex) { getLogger().log(Level.SEVERE, null, ex); } } private Logger getLogger() { return Logger.getLogger(getClass().getName()); } }