Add Registration functionality and tidy up
[WeStealzYourDataz.git] / index.md
1 % We Stealz Your Dataz (WSYD) social network
2
3 This document is created as `index.md` in Markdown text. It can be manually converted to HTML using pandoc with the command:
4
5     pandoc --standalone --self-contained --css styles.css --toc --from=markdown --to=html5 --output=index.html index.md
6
7 The [**To Do list**](todo.html).
8
9 ## Introduction
10
11 In this Java project I wanted to challenge myself to use some of the same concepts I've used in previous C++ projects in order to contrast and understand the different approaches taken in both languages.
12
13 The project criteria already suggested to me that the design would need to implement **multi-threading** and as there was no specific requirement to use a database I opted to use **object serialization** which would provide two useful functions: persisting the member data to file and passing pure java objects over the network.
14
15 I adopted the **Javadoc** standard for all my code annotations and as a result the **[entire code base is consistently documented](dist/javadoc/index.html)** in the same style as the Java API in HTML without requiring me to write separate documentation.
16
17 I used [**Remarkable**](Made with Remarkable!), a [**Markdown text**](http://daringfireball.net/projects/markdown/syntax) editor with live HTML preview, to create this report and allow the report and the Javadoc to link together as one HTML web.
18
19 After becoming familiar with the NetBeans IDE I explored its Test-Driven Development (TDD) support using **[Junit](http://junit.org)** and found it provided valuable feedback on bugs in my code that were not obvious before the tests were written.
20
21 I set out to implement the assessment criteria specified for a **First class** result.
22
23 ## Design
24
25 The criteria requires a minimum of three separate executable processes: GUI User client, Social Server and Chat Server. I opted to add a fourth: GUI Server Management client. This allowed me to implement the Social and Chat servers as true **background service daemons** and have them communicate with the GUI Server Management client over the network.
26
27 As well as displaying log messages received from the servers the GUI Server Management client allows the **independent restarting or stopping** of each server.
28
29 The GUI User client makes extensive use of Swing components. The NetBeans IDE is responsible for generating most of the GUI skeleton code for handling user actions via `ActionEvent` and `PropertyChange` event listeners and several function-specific child windows and dialogs for presentation during log-in, profile editing, chat and configuration. After the GUI skeleton code was complete I added support for the network services background threads and then implemented the links between them and the GUI components.
30
31 Since the criteria requires a range of network functionality shared across clients and servers I implemented a **[common network library](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/package-frame.html)**. This network library, and the server services it implements, needs to support **multi-threading** especially on the client since listening for incoming connections is an **operation that blocks** in the operating system kernel. If those blocking operations were performed on the GUI Event Dispatch thread it would cause **poor response** in the user interface.
32
33 Fortunately the [`javax.swing.SwingWorker`](http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html) class was designed especially for this purpose. As it implements the [`java.lang.Runnable`](http://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html) interface too it made the **perfect base class** for my own [`NetworkServerAbstract`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html) class because I could use it for both service daemon (non-GUI) and client (Swing GUI) applications.
34
35 I considered adopting an existing network protocol (or designing my own) for the communications between servers and clients and clients with clients. I considered Hyper Text Transport Protocol (HTTP) for the server to client connections. For client chat I looked at Internet Relay Chat (IRC) and its related Client To Client Protocol (CTCP) and the Direct Client Connect (DCC) sub-protocol (that supports file transfer) which together implement a server-mediated peer-to-peer (P2P) approach as a chat solution that has been in use since the 1990s.
36
37 The problem I found was that each *type* of communication would require a different protocol to be implemented. As well as requiring a lot of work to implement this had the risk of introducing **subtle hard-to-find runtime bugs** in the live communications.
38
39 I investigated using some form of pre-existing [`Message Queue`](http://blog.codepath.com/2013/01/06/asynchronous-processing-in-web-applications-part-2-developers-need-to-understand-message-queues/)  implementation such as Java `Enterprise Edition (EE)` [`Java Message Service (JMS)`](http://docs.oracle.com/javaee/6/tutorial/doc/bncdq.html) but decided most of these would be too over-engineered and complex for my requirements and therefore I would **create a simple message queue** implementation myself.
40
41 I'd already decided I'd use serialization for persisting member data and after looking at some examples of how easy it is to **serialize Java objects** over any kind of stream, including **network streams**, I realised it could make network communications reliable and consistent with minimal additional code both at run-time and at coding time since Java provides serialization as part of the Virtual Machine. The only requirement to support serialization is that each class of object that would be passed over the network should implement [`java.io.Serializable`](http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html) - which usually only requires a single addition:
42
43     public MyClass extends SomeClass implements java.io.Serializable {
44
45 This design decision makes it as **easy to pass an image or other file-type over the network** as it does to send simple text and with 100% reliability. In my implementation I wrapped each object being sent over the network in a [`NetworkMessage`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html) wrapper class that contains additional information such as sender and target service and the *intent* of the message.
46
47 A further issue I considered was **how the clients would discover the servers**. Since in the lab setting there will be no facility for adding Domain Name System (DNS) records to the local DNS server zone file it would require either:
48
49  1. hard-coding an IP address into the source-code and rebuilding the code each time the project was demonstrated
50  2. providing for the user to enter the IP address manually when each application starts
51  3. Using some form of automatic network discovery
52
53 I decided to opt for (3) implemented using [`java.net.MulticastSocket`](http://docs.oracle.com/javase/7/docs/api/java/net/MulticastSocket.html) with a fall-back to (2) in case automatic discovery fails.
54
55 Clients will create long-running Transmission Control Protocol (TCP) connections to the server for passing serialized [`NetworkMessage`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html) objects back and forth, starting with log-in.
56
57 Clients can discover each other via the Organisation-scope Multicast group, or if it isn't available, by requests to the Chat server which will mediate chat authorisations.
58
59 I implemented the asynchronous update from server to client requirement with User Datagram Protocol (UDP). If the Multicast group isn't active the update service will fall-back to using Unicast to each known client.
60
61 To avoid using something other than object serialization for sending notifications via UDP packets (which do not have support for streams) I used the [`NetworkMessage`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html)  [`serialize()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html#serialize(uk.ac.ntu.n0521366.wsyd.libs.net.NetworkMessage)) and [`deserialize()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html#deserialize(byte[])) methods to convert the object to and from a `byte[]` that can be transported by [`java.net.DatagramPacket`](http://docs.oracle.com/javase/7/docs/api/java/net/DatagramPacket.html).
62
63
64 ## Functionality
65
66 ==TODO:== Describe each application's core functionality and stand-out features
67
68 ### Social Server
69
70 ### Chat Sever
71
72 ### GUI Server Management client
73
74 ### GUI User client
75
76 ## Code
77
78 I began by designing and creating the skeleton GUI client using the NetBeans IDE.
79
80 Questions that came up during GUI client design led to coding [`WSYD_Member`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/WSYD_Member.html), the class that wraps the data structure representing each member of the WSYD social network. As well as data storage I implemented a static CSV parser [`createWYSD_Member()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/WSYD_Member.html#createWSYD_Member(java.lang.String)), the inverse method [`toString()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/WSYD_Member.html#toString()), and support for the [`java.lang.Comparable`](http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html) interface in [`compareTo()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/WSYD_Member.html#compareTo(uk.ac.ntu.n0521366.wsyd.libs.WSYD_Member)). I inherited serialization for free because all the attribute classes already support the [`java.io.Serializable`](http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html) interface.
81
82 The networking library was the next task. I investigated Java's networking support and looked at several code snippets and examples at sites such as *StackOverflow* as well as the official Java API documentation. I realised there were two requirements: the network services themselves, and the object passing.
83
84 Objects being passed need to encode the destination. For example, a "*Friend Is Online*" notification needs to be handled by a client method that knows what to do with that information. The network services only deal with transport not context. Therefore [`NetworkMessage`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html) objects know their [`sender`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html#getSender()), [`target`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html#setTarget(java.lang.String)) and the **`intent`** - `java.lang.String`s that allow received messages to be dispatched by the server service to the correct handler and for acknowledgements to be sent in return.
85
86 The mechanism for passing received objects from the server service to the GUI (or server process) implements a custom event [`NetworkMessageEvent`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessageEvent.html) which extends [`java.util.EventObject`](http://docs.oracle.com/javase/7/docs/api/java/util.EventObject.html) and adds  interface [`NetworkMessageEventGenerator`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessageEventGenerator.html) to [`NetworkServerAbstract`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html) which registers objects of classes that implement the [`NetworkMessageEventListener`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessageEventListener.html) interface. These objects are notified when a new [`NetworkMessage`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessage.html) is received. 
87
88 The network server classes all inherit their core functionality from [`NetworkServerAbstract`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html). Common functionality implemented here includes [`javax.swing.SwingWorker`](http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html) multi-threading, [`NetworkMessageEvent`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkMessageEvent.html) dispatching, the socket listener main loop in [`doInBackground()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html#doInBackground()), logging, and unsolicited outbound message queuing via [`queueMessage()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html#queueMessage(uk.ac.ntu.n0521366.wsyd.libs.net.NetworkMessage)) and [`dequeueMessage()`](dist/javadoc/uk/ac/ntu/n0521366/wsyd/libs/net/NetworkServerAbstract.html#dequeueMessage()).
89
90 The implementing classes `NetworkServerTCP`, `NetworkServerUDP` and `NetworkServerMulticast` add minimal code via method overrides to support protocol specific functionality.
91
92 ==TODO:== discuss other classes and notable features and coding/learning experiences
93
94 I used NetBeans **Action Items** to keep track of `TODO:` and `FIXME:` outstanding tasks, and `XXX:` to call attention to important notes.
95
96 ## Testing
97
98 I used the NetBeans-generated `JUnit version 4` test class templates as the basis for my **Unit Tests**, creating **close to 100% coverage** of the non-network library code. I didn't write tests for network connections functionality although they would have been very useful due to the amount of time, and the difficulty, I estimated it would require to develop them - much more than writing the network library itself.
99
100 ==TODO:== add examples of bugs the testing revealed and experiences in writing the more complicated test cases.
101
102
103 ## Bibliography
104
105 This is a list of many, but not all, of the very many resources I looked at in developing this project. Some were of more use than others but all of these contributed something to the development, design and coding.
106
107 ### References
108
109 [Administratively Scoped IPv4 Multicast Addresses](http://en.wikipedia.org/wiki/Multicast_address#Administratively_Scoped_IPv4_Multicast_addresses)
110
111
112 ### HTML formatted note taking
113
114 [Pandoc extended Markdown syntax](http://pandoc.org/demo/example9/pandocs-markdown.html)
115
116 [Markdown syntax](http://daringfireball.net/projects/markdown/syntax)
117
118 ### NetBeans IDE
119
120 [How to configure \@author tag](http://stackoverflow.com/questions/15922390/netbeans-how-to-change-author)
121
122 [Writing JUnit tests](https://netbeans.org/kb/docs/java/junit-intro.html#Exercise_20)
123
124 [How to set command line arguments for Run File](http://stackoverflow.com/questions/9168759/netbeans-how-to-set-command-line-arguments-in-java)
125
126
127 ### Java documentation
128
129 [Java Platform Standard Edition 7 Documentation](http://docs.oracle.com/javase/7/docs/index.html)
130
131 [Java SE 7 API](http://docs.oracle.com/javase/7/docs/api/)
132
133 [Controlling Access to Members of a Class](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
134
135 [Nested and Anonymous Classes - access to outer class variables](http://en.wikibooks.org/wiki/Java_Programming/Nested_Classes#Anonymous_Classes)
136
137
138 ### Java Generics
139
140 [Java Tutorials: Generics](https://docs.oracle.com/javase/tutorial/java/generics/)
141
142 [Java Tutorials: Generics (by Gilad Bracha)](https://docs.oracle.com/javase/tutorial/extra/generics/index.html)
143
144
145 ### Serialization
146
147 [Serialize Object over UDP](http://www.javaworld.com/article/2077539/learn-java/java-tip-40--object-transport-via-datagram-packets.html)
148
149 [Deep cloning techniques](http://howtodoinjava.com/2012/11/08/a-guide-to-object-cloning-in-java/)
150
151 [Why should a Comparator implement Serializable](http://stackoverflow.com/questions/8642012/why-should-a-comparator-implement-serializable)
152
153
154
155 ### Multi-threading
156
157 [Using SwingWorker to implement a UDP Client/Server](http://wenda.soso.io/questions/2765593/using-swingworker-to-implement-a-udp-client-server)
158
159 [Multi-threaded Network Server](http://www.tutorialspoint.com/javaexamples/net_multisoc.htm)
160
161 [How do I use SwingWorker in Java](http://stackoverflow.com/questions/782265/how-do-i-use-swingworker-in-java)
162
163 [Concurrency in Swing (multi-threading for background tasks)](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/)
164
165 [Synchronized Methods](https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html)
166
167 [Synchronized Statements](https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html)
168
169
170 ### Network
171
172 [Getting Network Interface Parameters](https://docs.oracle.com/javase/tutorial/networking/nifs/parameters.html)
173
174 [Testing a socket is listening on all network interfaces/wildcard interface](http://www.markhneedham.com/blog/2013/07/14/java-testing-a-socket-is-listening-on-all-network-interfaceswildcard-interface/)
175
176 [Socket Logging (network logger)](https://blogs.oracle.com/CoreJavaTechTips/entry/socket_logging)
177
178
179 ### Tutorials
180
181 [How to Write Doc Comments for the Javadoc Tool](http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html)
182
183 [Write Image to File](http://examples.javacodegeeks.com/core-java/io/java-imageio-write-image-to-file/)
184
185 [Iterating over a TreeMap](http://stackoverflow.com/questions/1318980/how-to-iterate-over-a-treemap)
186
187 [How do I call one constructor from another in Java](http://stackoverflow.com/questions/285177/how-do-i-call-one-constructor-from-another-in-java)
188
189 [James Gosling's explanation of why Java's byte is signed](http://stackoverflow.com/questions/3108297/james-goslings-explanation-of-why-javas-byte-is-signed)
190
191 [When to use flush() in Java](http://stackoverflow.com/questions/7300676/when-to-use-flush-in-java)
192
193 [How do I check if a file exists in Java](http://stackoverflow.com/questions/1816673/how-do-i-check-if-a-file-exists-in-java)
194
195 [Java String.equals() versus ==](http://stackoverflow.com/questions/767372/java-string-equals-versus)
196
197 [Calculating byte-size of Java object](http://stackoverflow.com/questions/3983360/calculating-byte-size-of-java-object)
198
199 [Mr. Happy Object teaches custom events](http://www.javaworld.com/article/2077333/core-java/mr-happy-object-teaches-custom-events.html)
200
201 [Multiple Swing Timers](https://www.daniweb.com/software-development/java/threads/350345/multipe-swing-timers)
202
203 [Launching a browser for a web page](http://docs.oracle.com/javase/6/docs/api/java/awt/Desktop.html#browse%28java.net.URI%29)
204
205 [Jbutton that does not show focus](http://www.java2s.com/Code/Java/Swing-JFC/CreateaJButtonthatdoesnotshowfocus.htm)
206
207 [Set JFrame iconImage in NetBeans](http://www.areaofthoughts.com/2011/08/netbeans-jframe-properties-iconimage.html)
208
209 [JTable scrolling to a specific row](http://stackoverflow.com/questions/853020/jtable-scrolling-to-a-specified-row-index)