*/
package uk.ac.ntu.n0521366.wsyd.libs.net;
-import java.text.MessageFormat;
import java.net.SocketException;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.ArrayList;
+import java.text.MessageFormat;
import java.util.List;
import java.util.logging.Logger;
import java.util.logging.Level;
* Can be instantiated once by objects of any sub-class.
*/
@SuppressWarnings("NonConstantLogger")
- protected static Logger LOGGER = null;
-
+ protected Logger LOGGER;
+
/**
* Inject simulated received NetworkMessages.
*
*/
WSYD_SocketAddress _socketAddress;
+ /**
+ * Maintains up-to-date map of services and their IP addresses .
+ */
protected ServiceAddressMap _serviceToHostMap;
- private final NetworkMessageEventListenerManager _eventManager;
/**
- *
- * @param level message importance
- * @param title source identifier
- * @param formatter parameter Formatter for log message
- * @param parameters variable length list of replaceable parameters for formatter
+ * Manages NetworkEvent listeners and sends them Events when needed.
*/
- protected static void log(Level level, String title, String formatter, ArrayList<String> parameters) {
- if (LOGGER == null)
- return;
- // formatter = "{" + Integer.toString(parameters.size()) + "}: " + formatter;
- // parameters.add(title);
- LOGGER.logp(level, title, null, MessageFormat.format(formatter, parameters.toArray()));
- }
- /**
- *
- * @param level message importance
- * @param title source identifier
- * @param message the log entry
- */
- protected static void log(Level level, String title, String message) {
- if (LOGGER == null)
- return;
- LOGGER.logp(level, title, null, message);
- }
+ private final NetworkMessageEventListenerManager _eventManager;
/**
- * Set the log level for the server
- * @param level a new log level
- * @return the old log level
+ * Custom simplified logging function.
+ *
+ * Encapsulates the commonly repeated code of Logger method calls
+ *
+ * @param level the Logger.Level of this message
+ * @param format MessageFormat.format() formatter
+ * @param message zero or more arguments for MessageFormat.format() to process
*/
- public Level setLogLevel(Level level) {
- Level result = Level.OFF;
- if (LOGGER != null) {
- Level temp = LOGGER.getLevel();
- LOGGER.setLevel(level);
- result = temp;
- }
- return result;
+ protected void logp(Level level, String format, Object... message) {
+ if (LOGGER != null)
+ LOGGER.logp(level, _title, null, MessageFormat.format(format, (Object[]) message));
}
-
+
/**
* Default constructor.
*/
NetworkServerAbstract() {
- this._connectionCount = 0;
- this._title = null;
- this._socketAddress = null;
- this._serviceToHostMap = null;
- this._eventManager = null;
+ this(null, null, null, null, null);
}
/**
- * Construct the server with a Logger.
+ * Construct a fully customised service.
*
* No socket is opened.
*
* @param socketAddress The socket to listen on
* @param title source identifier for use in log messages and sent NetworkMessage objects
* @param serviceToHostMap the map object used for host <> InetSocketAddress lookups
- * @param logger An instance of Logger to be used by all objects of this class
+ * @param eventManager the NetworkMessage event listener manager
+ * @param logger An instance of Logger
*/
- public NetworkServerAbstract(WSYD_SocketAddress socketAddress, String title, ServiceAddressMap serviceToHostMap, Logger logger) {
+ public NetworkServerAbstract(WSYD_SocketAddress socketAddress, String title, ServiceAddressMap serviceToHostMap, NetworkMessageEventListenerManager eventManager, Logger logger) {
this._connectionCount = 0;
this._title = title;
this._socketAddress = socketAddress;
this._serviceToHostMap = serviceToHostMap;
- this._eventManager = new NetworkMessageEventListenerManager();
- if (LOGGER == null) // do not replace existing logger reference
- LOGGER = logger;
+ this._eventManager = eventManager;
+ this.LOGGER = logger;
}
/**
- * Construct the server without a Logger.
+ * Construct a service with a default NetworkMessageEventListenerManager and a Logger.
+ *
+ * No socket is opened.
+ *
+ * @param socketAddress The socket to listen on
+ * @param title source identifier for use in log messages and sent NetworkMessage objects
+ * @param serviceToHostMap the map object used for host <> InetSocketAddress lookups
+ * @param logger a Logger instance
+ */
+ public NetworkServerAbstract(WSYD_SocketAddress socketAddress, String title, ServiceAddressMap serviceToHostMap, Logger logger) {
+ this(socketAddress, title, serviceToHostMap, new NetworkMessageEventListenerManager(), logger);
+ }
+
+ /**
+ * Construct a service with a default NetworkMessageEventListenerManager and without a Logger.
*
* No socket is opened.
*
return _socketAddress;
}
+ /**
+ * Change the title of this service.
+ *
+ * @param newTitle replacement title
+ * @return original title
+ */
+ public String setTitle(String newTitle) {
+ String oldTitle = _title;
+ _title = newTitle != null ? newTitle : _title;
+ return oldTitle;
+ }
+
+ /**
+ * Get current service title.
+ * @return the title
+ */
+ public String getTitle() {
+ return _title;
+ }
+
/**
* Enable or disable simulated received packet injection.
*
*/
@Override
public Integer doInBackground() {
- ArrayList<String> logMessages = new ArrayList<>();
try {
- logMessages.add(_socketAddress.toString());
- log(Level.INFO, _title, "Opening socket {0}", logMessages);
+ logp(Level.INFO, "Opening socket {0}", _socketAddress.toString());
this.serverOpen();
}
catch(SocketException e) {
- logMessages.clear();
- logMessages.add(_socketAddress.getAddress().toString());
- logMessages.add(Integer.toString(_socketAddress.getPort()));
- logMessages.add(_socketAddress.getProtocol().toString());
- log(Level.SEVERE, _title, "{0}: Unable to open socket on {1}:{2} {3}", logMessages);
+ logp(Level.SEVERE, "Unable to open socket {0}", _socketAddress.toString());
}
// unless cancelled keep waiting for new packets or connections
// send a queued message
NetworkMessage temp = this.sendMessage();
if (temp != null) {
- if (!this.serverSend(temp)) {
- logMessages.clear();
- logMessages.add(temp.getSender());
- logMessages.add(temp.getTarget());
- log(Level.WARNING, _title, "Unable to send message from {0} to {1}", logMessages);
- }
+ if (!this.serverSend(temp))
+ logp(Level.WARNING, "Unable to send message from {0} to {1}", temp.getSender(), temp.getTarget());
}
}
try {
- logMessages.clear();
- logMessages.add(_socketAddress.toString());
- log(Level.INFO, _title, "Closing socket {0}", logMessages);
+ logp(Level.INFO, "Closing socket {0}", _socketAddress.toString());
this.serverClose();
}
catch(SocketException e) {
- logMessages.clear();
- logMessages.add(_socketAddress.getAddress().toString());
- logMessages.add(Integer.toString(_socketAddress.getPort()));
- logMessages.add(_socketAddress.getProtocol().toString());
- log(Level.SEVERE, _title, "{0}: Unable to close socket on {1}:{2} {3}", logMessages);
+ logp(Level.SEVERE, "Unable to close socket on {0}", _socketAddress.toString());
}
return this._connectionCount;