summaryrefslogtreecommitdiff
path: root/src/main/TweetShell.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/TweetShell.java')
-rw-r--r--src/main/TweetShell.java150
1 files changed, 122 insertions, 28 deletions
diff --git a/src/main/TweetShell.java b/src/main/TweetShell.java
index 5e5d074..fa1fb49 100644
--- a/src/main/TweetShell.java
+++ b/src/main/TweetShell.java
@@ -5,17 +5,21 @@ import io.OAuthRequester;
import io.StreamImpl;
import java.io.IOException;
import java.util.Arrays;
+import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Scanner;
import java.util.Set;
+import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import mining.Stream;
import mining.TwitterApi;
import org.json.JSONException;
import org.json.JSONObject;
+import provider.CompositeResultListener;
import provider.ExceptionListener;
import provider.ResultListener;
+import support.ClassEnabledTracker;
import utils.Configuration;
/**
@@ -42,7 +46,13 @@ public class TweetShell implements TwitterApi.PinSupplier {
stream_cached = new StreamImpl(requester);
StreamImpl streamObserver = (StreamImpl) stream_cached;
streamObserver.setExceptionListener(handler);
- streamObserver.setResultListener(new StreamHandler());
+
+ CompositeResultListener listeners = new CompositeResultListener();
+ streamObserver.setResultListener(listeners);
+ // by default, store something that counts responses
+ listeners.register(new TweetCounter());
+ // and something that prints tweets to console.
+ listeners.register(handler);
}
return stream_cached;
}
@@ -155,7 +165,9 @@ public class TweetShell implements TwitterApi.PinSupplier {
close("Close the stream"),
exit("Returns to shell"),
help("Get help"),
- target("Set output target: {file, shell}.", 1);
+ target("Set output target: one or more of {file, shell} with optional."
+ + "'-' (disable) or '+' (enable) prefix. Without prefix, "
+ + "only that target is enabled.");
private final String description;
private final int paramCount;
@@ -258,37 +270,119 @@ public class TweetShell implements TwitterApi.PinSupplier {
throw new NoSuchElementException();
case target:
StreamImpl stream = (StreamImpl) getStream();
- ResultListener oldListener = stream.getResultListener();
- switch (params[0]) {
- case "file":
- if (!(oldListener instanceof DataWriter)) {
- Configuration config = Configuration.getConfig();
-
- String profilesFilename = config.getProperty(DataWriter.CFG_PROFILE_FILENAME);
- String tweetsFilename = config.getProperty(DataWriter.CFG_TWEETS_FILENAME);
-
- stream.setResultListener(new DataWriter(profilesFilename, tweetsFilename));
-
- // save the changes to the config.
- config.save();
- }
- break;
- case "shell":
- if (oldListener instanceof DataWriter) {
- ((DataWriter) oldListener).close();
- }
- if (!(oldListener instanceof StreamHandler)) {
- stream.setResultListener(new StreamHandler());
- }
- break;
- default:
- System.err.println("Unrecognized target " + params[0]);
- break;
+ CompositeResultListener rls;
+ rls = (CompositeResultListener) stream.getResultListener();
+ if (params.length > 0) {
+ configureTargets(rls, params);
+ } else {
+ ClassEnabledTracker<ResultListener> targets = getPossibleTargets(rls);
+ // print the names of all targets that are enabled
+ System.out.print("Enabled targets:");
+ for (String name : targets.getNames()) {
+ System.out.print(" " + name);
+ }
+ System.out.println();
}
break;
default:
throw new AssertionError(command.name());
}
+ }
+
+ /**
+ * @param stream An instance for which open targets apply to.
+ * @return All targets that can be disabled or enabled.
+ */
+ private ClassEnabledTracker<ResultListener> getPossibleTargets(CompositeResultListener rls) {
+ Map<String, Class<? extends ResultListener>> targets = new TreeMap<>();
+ targets.put("file", DataWriter.class);
+ targets.put("shell", StreamHandler.class);
+
+ ClassEnabledTracker<ResultListener> targetFoo = new ClassEnabledTracker<>(targets);
+ targetFoo.disableAll();
+ targetFoo.enableClasses(rls.getRegistered());
+ return targetFoo;
+ }
+
+ /**
+ * Process enable and disable target parameters.
+ */
+ private void configureTargets(CompositeResultListener rls, String[] params) {
+ ClassEnabledTracker<ResultListener> targets = getPossibleTargets(rls);
+
+ for (String type : params) {
+ String name;
+ // whether to remove, add targets or restrict to one
+ if (type.startsWith("-") || type.startsWith("+")) {
+ name = type.substring(1);
+ } else {
+ name = type;
+ }
+ if (!targets.has(name)) {
+ System.err.println("Unrecognized target: " + name);
+ continue;
+ }
+ // queue for enable or disable
+ if (type.startsWith("-")) {
+ targets.disable(name);
+ } else if (type.startsWith("+")) {
+ targets.enable(name);
+ } else {
+ targets.disableAll();
+ targets.enable(name);
+ }
+ }
+ for (String name : targets.getDisabled()) {
+ if (disableTarget(rls, targets.getClassByName(name))) {
+ System.err.println("Disabled " + name);
+ }
+ }
+ for (String name : targets.getEnabled()) {
+ if (enableTarget(rls, targets.getClassByName(name))) {
+ System.err.println("Enabled " + name);
+ }
+ }
+ }
+
+ private boolean enableTarget(CompositeResultListener rls,
+ Class<? extends ResultListener> rlCls) {
+ ResultListener oldListener = rls.findListener(rlCls);
+
+ // don't add it again if already activated
+ if (oldListener != null) {
+ return false;
+ }
+
+ if (rlCls == DataWriter.class) {
+ Configuration config = Configuration.getConfig();
+
+ String profilesFilename = config.getProperty(DataWriter.CFG_PROFILE_FILENAME);
+ String tweetsFilename = config.getProperty(DataWriter.CFG_TWEETS_FILENAME);
+
+ rls.register(new DataWriter(profilesFilename, tweetsFilename));
+ // save the changes to the config.
+ config.save();
+ } else if (rlCls == StreamHandler.class) {
+ rls.register(new StreamHandler());
+ }
+ return true;
+ }
+
+ private boolean disableTarget(CompositeResultListener rls,
+ Class<? extends ResultListener> rlCls) {
+ ResultListener oldListener = rls.findListener(rlCls);
+
+ // no need for action if not activated
+ if (oldListener == null) {
+ return false;
+ }
+
+ rls.unregister(oldListener);
+ // do we need to cleanup something?
+ if (oldListener instanceof DataWriter) {
+ ((DataWriter) oldListener).close();
+ }
+ return true;
}
}