├── scripts
├── client.bat
├── server.bat
├── make-jar.bat
├── client.sh
├── server.sh
└── make-jar.sh
├── images
├── avatar.png
├── msgbox-info.png
├── login-banner.psd
├── msgbox-error.psd
└── connection-banner.psd
├── src
└── main
│ ├── resources
│ ├── app.properties
│ ├── images
│ │ ├── avatar.png
│ │ ├── banner.png
│ │ ├── offline.png
│ │ ├── online.png
│ │ ├── profile.png
│ │ ├── button-send.png
│ │ ├── login-banner.png
│ │ ├── msgbox-error.png
│ │ ├── msgbox-info.png
│ │ ├── personal-logo.png
│ │ └── connection-banner.png
│ ├── layouts
│ │ ├── dynamic-text-area.fxml
│ │ ├── chat-message-mine.fxml
│ │ ├── chat-message-friend.fxml
│ │ ├── password-dialog.fxml
│ │ ├── friend-list-view-cell.fxml
│ │ ├── chat-window.fxml
│ │ ├── register-window.fxml
│ │ ├── login-window.fxml
│ │ ├── connection-window.fxml
│ │ ├── profile-window.fxml
│ │ ├── friend-list-window.fxml
│ │ └── main-window.fxml
│ ├── css
│ │ ├── chatmsg.css
│ │ └── chatbox.css
│ └── log4j.properties
│ └── java
│ └── com
│ └── blogspot
│ └── sontx
│ └── chatsocket
│ ├── lib
│ ├── Function.java
│ ├── Callback.java
│ ├── bean
│ │ ├── ResponseCode.java
│ │ ├── RequestCode.java
│ │ ├── Response.java
│ │ ├── UpdatePassword.java
│ │ ├── Request.java
│ │ ├── ChatMessage.java
│ │ ├── LoginInfo.java
│ │ ├── RegisterInfo.java
│ │ └── Profile.java
│ ├── view
│ │ ├── ViewFactory.java
│ │ ├── BaseView.java
│ │ ├── WindowUtils.java
│ │ ├── TwoLineJLabel.java
│ │ ├── AbstractViewFactory.java
│ │ ├── FitImageJLabel.java
│ │ ├── ClickableJLabel.java
│ │ ├── AbstractSwingWindow.java
│ │ ├── AbstractJavaFxWindow.java
│ │ └── javafx
│ │ │ └── custom
│ │ │ └── DynamicTextArea.java
│ ├── service
│ │ ├── message
│ │ │ ├── MessageType.java
│ │ │ ├── MessageBox.java
│ │ │ ├── SwingMessageBox.java
│ │ │ └── JavaFxMessageBox.java
│ │ ├── Service.java
│ │ ├── event
│ │ │ ├── StopServiceEvent.java
│ │ │ └── ShowMessageBoxEvent.java
│ │ ├── BackgroundService.java
│ │ ├── MessageBoxService.java
│ │ └── AbstractService.java
│ ├── event
│ │ └── AppShutdownEvent.java
│ ├── settings
│ │ ├── SettingsLoader.java
│ │ └── Setting.java
│ ├── Presenter.java
│ ├── bo
│ │ ├── ObjectAdapter.java
│ │ ├── ObjectTransmission.java
│ │ ├── AbstractResource.java
│ │ ├── ByteTransmission.java
│ │ ├── LayoutsResource.java
│ │ ├── SocketByteTransmission.java
│ │ ├── DefaultObjectTransmission.java
│ │ ├── SerializableObjectAdapter.java
│ │ └── ImagesResource.java
│ ├── NotRegisteredException.java
│ ├── thread
│ │ ├── ThreadInvoker.java
│ │ ├── JavaFxThreadInvoker.java
│ │ ├── AbstractThreadInvoker.java
│ │ └── SwingThreadInvoker.java
│ ├── utils
│ │ ├── StreamUtils.java
│ │ ├── NetworkUtils.java
│ │ └── Security.java
│ ├── platform
│ │ ├── Platform.java
│ │ ├── SwingPlatform.java
│ │ ├── JavaFxPlatform.java
│ │ └── AbstractPlatform.java
│ ├── AbstractPresenter.java
│ └── Component.java
│ ├── client
│ ├── event
│ │ ├── OpenRegisterEvent.java
│ │ ├── ConnectedToServerEvent.java
│ │ ├── UpdateFriendListEvent.java
│ │ ├── UpdatePasswordEvent.java
│ │ ├── ClientShutdownEvent.java
│ │ ├── LoginEvent.java
│ │ ├── ConnectToServerEvent.java
│ │ ├── OpenChatEvent.java
│ │ ├── LoggedEvent.java
│ │ ├── RegisterEvent.java
│ │ ├── UpdateProfileEvent.java
│ │ ├── OpenMyProfileEvent.java
│ │ ├── RegisteredEvent.java
│ │ ├── ChatWindowClosedEvent.java
│ │ ├── FriendInfoChangedEvent.java
│ │ ├── SendChatMessageEvent.java
│ │ ├── MyAccountInfoReceivedEvent.java
│ │ ├── ChatMessageReceivedEvent.java
│ │ └── FriendListReceivedEvent.java
│ ├── AppClient.java
│ ├── model
│ │ ├── Client.java
│ │ ├── handler
│ │ │ ├── ResponseHandler.java
│ │ │ ├── DoNothingResponseHandler.java
│ │ │ ├── AbstractResponseHandler.java
│ │ │ ├── PasswordResponseHandler.java
│ │ │ ├── FriendInfoResponseHandler.java
│ │ │ ├── LoginResponseHandler.java
│ │ │ ├── RegisterResponseHandler.java
│ │ │ ├── AccountInfoResponseHandler.java
│ │ │ ├── UpdateProfileResponseHandler.java
│ │ │ ├── FriendListResponseHandler.java
│ │ │ ├── ChatMessageResponseHandler.java
│ │ │ └── ResponseHandlerFactory.java
│ │ ├── ChattingManager.java
│ │ └── UserProfile.java
│ ├── ClientSettings.java
│ ├── view
│ │ ├── RegisterView.java
│ │ ├── javafx
│ │ │ ├── custom
│ │ │ │ ├── ChatMessageInternal.java
│ │ │ │ ├── ChatMessageCell.java
│ │ │ │ └── FriendListViewCell.java
│ │ │ ├── JavaFxViewFactory.java
│ │ │ ├── LoginWindow.java
│ │ │ ├── RegisterWindow.java
│ │ │ ├── ConnectionWindow.java
│ │ │ ├── ChatWindow.java
│ │ │ ├── ProfileWindow.java
│ │ │ ├── PasswordDialog.java
│ │ │ └── FriendListWindow.java
│ │ ├── ConnectionView.java
│ │ ├── LoginView.java
│ │ ├── ChatView.java
│ │ ├── ProfileView.java
│ │ ├── swing
│ │ │ ├── SwingViewFactory.java
│ │ │ ├── custom
│ │ │ │ ├── FriendEntry.java
│ │ │ │ └── FriendCellRenderer.java
│ │ │ ├── PasswordDialog.java
│ │ │ ├── ConnectionWindow.java
│ │ │ └── LoginWindow.java
│ │ └── FriendListView.java
│ ├── platform
│ │ ├── ClientSwingPlatform.java
│ │ └── ClientJavaFxPlatform.java
│ └── presenter
│ │ ├── RegisterPresenter.java
│ │ ├── LoginPresenter.java
│ │ ├── ConnectionPresenter.java
│ │ ├── ProfilePresenter.java
│ │ └── ChatPresenter.java
│ ├── server
│ ├── view
│ │ ├── LogView.java
│ │ ├── MainView.java
│ │ ├── swing
│ │ │ ├── SwingViewFactory.java
│ │ │ └── AddressDialog.java
│ │ └── javafx
│ │ │ ├── JavaFxViewFactory.java
│ │ │ ├── AddressDialog.java
│ │ │ └── MainWindow.java
│ ├── event
│ │ ├── StopServerEvent.java
│ │ ├── StartServerEvent.java
│ │ ├── ServerStatusChangedEvent.java
│ │ ├── LookupWorkerEvent.java
│ │ ├── AccountInfoChangedEvent.java
│ │ ├── ShutdownWorkerEvent.java
│ │ ├── ShutdownServerEvent.java
│ │ ├── RequestReceivedEvent.java
│ │ └── ForwardChatMessageEvent.java
│ ├── AppServer.java
│ ├── model
│ │ ├── handler
│ │ │ ├── RequestHandler.java
│ │ │ ├── DoNothingRequestHandler.java
│ │ │ ├── AccountInfoRequestHandler.java
│ │ │ ├── FriendListRequestHandler.java
│ │ │ ├── ChatMessageRequestHandler.java
│ │ │ ├── RequestHandlerFactory.java
│ │ │ ├── UpdateProfileRequestHandler.java
│ │ │ ├── PasswordRequestHandler.java
│ │ │ ├── AbstractRequestHandler.java
│ │ │ ├── LoginRequestHandler.java
│ │ │ └── RegisterRequestHandler.java
│ │ ├── Server.java
│ │ ├── account
│ │ │ ├── Account.java
│ │ │ ├── AccountStorage.java
│ │ │ ├── AccountManager.java
│ │ │ └── AccountManagerImpl.java
│ │ ├── Worker.java
│ │ ├── RequestRouter.java
│ │ └── SocketServer.java
│ ├── ServerSettings.java
│ ├── platform
│ │ ├── ServerSwingPlatform.java
│ │ └── ServerJavaFxPlatform.java
│ └── presenter
│ │ ├── Log4jUIAppender.java
│ │ └── MainPresenter.java
│ ├── Program.java
│ ├── AppConfig.java
│ └── Bootstrap.java
├── .travis.yml
├── LICENSE
├── .gitignore
└── pom.xml
/scripts/client.bat:
--------------------------------------------------------------------------------
1 | start homechat.jar --mode=client
--------------------------------------------------------------------------------
/scripts/server.bat:
--------------------------------------------------------------------------------
1 | start homechat.jar --mode=server
--------------------------------------------------------------------------------
/scripts/make-jar.bat:
--------------------------------------------------------------------------------
1 | cd ../
2 | mvn clean compile assembly:single
--------------------------------------------------------------------------------
/scripts/client.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | java -jar homechat.jar --mode=client
--------------------------------------------------------------------------------
/scripts/server.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | java -jar homechat.jar --mode=server
--------------------------------------------------------------------------------
/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/images/avatar.png
--------------------------------------------------------------------------------
/scripts/make-jar.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | cd ../
3 | mvn clean compile assembly:single
--------------------------------------------------------------------------------
/images/msgbox-info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/images/msgbox-info.png
--------------------------------------------------------------------------------
/images/login-banner.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/images/login-banner.psd
--------------------------------------------------------------------------------
/images/msgbox-error.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/images/msgbox-error.psd
--------------------------------------------------------------------------------
/images/connection-banner.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/images/connection-banner.psd
--------------------------------------------------------------------------------
/src/main/resources/app.properties:
--------------------------------------------------------------------------------
1 | AppName=Homechat
2 | AppVersion=v2.1.0
3 | HomePageUrl=http://www.code4bugs.com/
--------------------------------------------------------------------------------
/src/main/resources/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/src/main/resources/images/avatar.png
--------------------------------------------------------------------------------
/src/main/resources/images/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/src/main/resources/images/banner.png
--------------------------------------------------------------------------------
/src/main/resources/images/offline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/src/main/resources/images/offline.png
--------------------------------------------------------------------------------
/src/main/resources/images/online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/src/main/resources/images/online.png
--------------------------------------------------------------------------------
/src/main/resources/images/profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/src/main/resources/images/profile.png
--------------------------------------------------------------------------------
/src/main/resources/images/button-send.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/src/main/resources/images/button-send.png
--------------------------------------------------------------------------------
/src/main/resources/images/login-banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/src/main/resources/images/login-banner.png
--------------------------------------------------------------------------------
/src/main/resources/images/msgbox-error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/src/main/resources/images/msgbox-error.png
--------------------------------------------------------------------------------
/src/main/resources/images/msgbox-info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/src/main/resources/images/msgbox-info.png
--------------------------------------------------------------------------------
/src/main/resources/images/personal-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/src/main/resources/images/personal-logo.png
--------------------------------------------------------------------------------
/src/main/resources/images/connection-banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sontx/chat-socket/HEAD/src/main/resources/images/connection-banner.png
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk: openjdk8
3 | before_install:
4 | - sudo apt update
5 | - sudo apt install openjfx
6 | script: mvn clean verify
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/Function.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib;
2 |
3 | public interface Function {
4 | T call();
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/OpenRegisterEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | public class OpenRegisterEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/Callback.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib;
2 |
3 | public interface Callback {
4 | void call(T obj);
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bean/ResponseCode.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bean;
2 |
3 | public enum ResponseCode {
4 | OK,
5 | Fail
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/view/ViewFactory.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.view;
2 |
3 | public interface ViewFactory {
4 | T create(Class viewType);
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/service/message/MessageType.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.service.message;
2 |
3 | public enum MessageType {
4 | Info,
5 | Error
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/event/AppShutdownEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.event;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class AppShutdownEvent {
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/ConnectedToServerEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class ConnectedToServerEvent {
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/UpdateFriendListEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class UpdateFriendListEvent {
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/view/LogView.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.view;
2 |
3 | public interface LogView {
4 | void appendLog(String message);
5 |
6 | void clearLog();
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/settings/SettingsLoader.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.settings;
2 |
3 | public interface SettingsLoader {
4 | T get(Class settingType);
5 |
6 | void save();
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/service/message/MessageBox.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.service.message;
2 |
3 | public interface MessageBox {
4 | void show(String caption, String text, MessageType type);
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/event/StopServerEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.event;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * Stops server command.
7 | */
8 | @Data
9 | public class StopServerEvent {
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/Program.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket;
2 |
3 | /**
4 | * The main entry of application.
5 | */
6 | public class Program {
7 | public static void main(String[] args) {
8 | new Bootstrap().boot(args);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/Presenter.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.platform.Platform;
4 |
5 | public interface Presenter {
6 | void show();
7 |
8 | void setPlatform(Platform platform);
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/resources/layouts/dynamic-text-area.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/AppClient.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.platform.Platform;
4 |
5 | /**
6 | * Client entry point.
7 | */
8 | public interface AppClient {
9 | void start(Platform platform);
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/AppServer.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.platform.Platform;
4 |
5 | /**
6 | * Server entry point.
7 | */
8 | public interface AppServer {
9 | void start(Platform platform);
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bo/ObjectAdapter.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bo;
2 |
3 | /**
4 | * Convert bytes to object and vice versa.
5 | */
6 | public interface ObjectAdapter {
7 | byte[] objectToBytes(Object obj);
8 |
9 | Object bytesToObject(byte[] bytes);
10 | }
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bean/RequestCode.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bean;
2 |
3 | public enum RequestCode {
4 | AccountInfo,
5 | FriendList,
6 | ChatMessage,
7 | Login,
8 | Register,
9 | UpdatePassword,
10 | UpdateProfile,
11 | FriendInfoUpdated
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/model/handler/RequestHandler.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.model.handler;
2 |
3 | import com.blogspot.sontx.chatsocket.server.event.RequestReceivedEvent;
4 |
5 | public interface RequestHandler {
6 | void handle(RequestReceivedEvent event) throws Exception;
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/UpdatePasswordEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.UpdatePassword;
4 | import lombok.Data;
5 |
6 | @Data
7 | public class UpdatePasswordEvent {
8 | private UpdatePassword updatePassword;
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/NotRegisteredException.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib;
2 |
3 | public class NotRegisteredException extends RuntimeException {
4 | public NotRegisteredException() {
5 | }
6 |
7 | public NotRegisteredException(String msg) {
8 | super(msg);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/ServerSettings.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.settings.Setting;
4 | import lombok.Data;
5 |
6 | @Data
7 | @Setting(key = "server")
8 | public class ServerSettings {
9 | private String ip;
10 | private int port;
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/model/Client.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.model;
2 |
3 | import java.io.Closeable;
4 |
5 | /**
6 | * Lowest layer that communicates with {@link com.blogspot.sontx.chatsocket.server.model.Server}.
7 | */
8 | public interface Client extends Closeable {
9 | void start();
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/service/Service.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.service;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.platform.Platform;
4 |
5 | public interface Service {
6 | int getId();
7 |
8 | void setPlatform(Platform platform);
9 |
10 | void start();
11 |
12 | void stop();
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/service/event/StopServiceEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.service.event;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | @Data
8 | @NoArgsConstructor
9 | @AllArgsConstructor
10 | public class StopServiceEvent {
11 | private int id;
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/ClientShutdownEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | @Data
8 | @NoArgsConstructor
9 | @AllArgsConstructor
10 | public class ClientShutdownEvent {
11 | private Exception reason;
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/model/Server.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.model;
2 |
3 | import java.io.Closeable;
4 |
5 | /**
6 | * Communication server that will wait for connections from clients and routes these connections
7 | * to {@link Worker}.
8 | */
9 | public interface Server extends Closeable {
10 | void start();
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/ClientSettings.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.settings.Setting;
4 | import lombok.Data;
5 |
6 | @Data
7 | @Setting(key = "client")
8 | public class ClientSettings {
9 | private String serverIp;
10 | private int serverPort;
11 | private String loggedUserName;
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/LoginEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | @Data
8 | @NoArgsConstructor
9 | @AllArgsConstructor
10 | public class LoginEvent {
11 | private String username;
12 | private String password;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/view/BaseView.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.view;
2 |
3 | public interface BaseView {
4 | void showWindow();
5 |
6 | void closeWindow();
7 |
8 | void setTitle(String title);
9 |
10 | void setOnClosingListener(Runnable listener);
11 |
12 | void setMainWindow();
13 |
14 | boolean isMainWindow();
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/model/account/Account.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.model.account;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import lombok.Data;
5 |
6 | @Data
7 | class Account {
8 | private String id;
9 | private String username;
10 | private String passwordHash;
11 | private Profile profile;
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/model/handler/ResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.model.handler;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Response;
4 | import com.blogspot.sontx.chatsocket.lib.bo.ObjectTransmission;
5 |
6 | public interface ResponseHandler {
7 | void handle(ObjectTransmission transmission, Response response) throws Exception;
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/ConnectToServerEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | @Data
8 | @NoArgsConstructor
9 | @AllArgsConstructor
10 | public class ConnectToServerEvent {
11 | private String serverIp;
12 | private int serverPort;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/model/handler/DoNothingRequestHandler.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.model.handler;
2 |
3 | import com.blogspot.sontx.chatsocket.server.event.RequestReceivedEvent;
4 |
5 | public class DoNothingRequestHandler extends AbstractRequestHandler {
6 | @Override
7 | public void handle(RequestReceivedEvent event) throws Exception {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/OpenChatEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | public class OpenChatEvent {
12 | private Profile chatWith;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/view/RegisterView.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.view;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.view.BaseView;
4 |
5 | public interface RegisterView extends BaseView {
6 | void setRegisterButtonClickListener(Runnable listener);
7 |
8 | String getUsername();
9 |
10 | String getPassword();
11 |
12 | String getDisplayName();
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/LoggedEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @AllArgsConstructor
10 | @NoArgsConstructor
11 | public class LoggedEvent {
12 | private Profile loggedAccount;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/resources/css/chatmsg.css:
--------------------------------------------------------------------------------
1 | .chatmsg-content {
2 | -fx-background-radius: 5;
3 | -fx-padding: 8px;
4 | -fx-min-width: 80px;
5 | -fx-wrap-text: true;
6 | -fx-alignment: center;
7 | }
8 |
9 | .chatmsg-content--friend {
10 | -fx-background-color: #f1f0f0;
11 | -fx-text-fill: #4b4f56;
12 | }
13 |
14 | .chatmsg-content--mine {
15 | -fx-background-color: #4080ff;
16 | -fx-text-fill: #fff;
17 | }
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/RegisterEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | @Data
8 | @NoArgsConstructor
9 | @AllArgsConstructor
10 | public class RegisterEvent {
11 | private String username;
12 | private String password;
13 | private String displayName;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/UpdateProfileEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | public class UpdateProfileEvent {
12 | private Profile profile;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/view/javafx/custom/ChatMessageInternal.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.view.javafx.custom;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | @Data
8 | @NoArgsConstructor
9 | @AllArgsConstructor
10 | public class ChatMessageInternal {
11 | private String content;
12 | private boolean isMe;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bo/ObjectTransmission.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bo;
2 |
3 | import java.io.Closeable;
4 | import java.io.IOException;
5 |
6 | /**
7 | * Communicating based on object stream.
8 | */
9 | public interface ObjectTransmission extends Closeable {
10 | void sendObject(Object obj) throws IOException;
11 |
12 | Object receiveObject() throws IOException;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/thread/ThreadInvoker.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.thread;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.Function;
4 |
5 | public interface ThreadInvoker {
6 | void invokeLater(Runnable runnable);
7 |
8 | void invokeAndWait(Runnable runnable);
9 |
10 | T invokeWithResult(Function func);
11 |
12 | void executeAsync(Runnable callback);
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/OpenMyProfileEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | public class OpenMyProfileEvent {
12 | private Profile myProfile;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/RegisteredEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | public class RegisteredEvent {
12 | private Profile registeredAccount;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/settings/Setting.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.settings;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | @Retention(RetentionPolicy.RUNTIME)
9 | @Target(ElementType.TYPE)
10 | public @interface Setting {
11 | String key();
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/event/StartServerEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.event;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | /**
8 | * Starts server command.
9 | */
10 | @Data
11 | @NoArgsConstructor
12 | @AllArgsConstructor
13 | public class StartServerEvent {
14 | private String ip;
15 | private int port;
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/ChatWindowClosedEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | public class ChatWindowClosedEvent {
12 | private Profile chatWith;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bean/Response.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bean;
2 |
3 | import lombok.Data;
4 |
5 | import java.io.Serializable;
6 |
7 | @Data
8 | public class Response implements Serializable {
9 | private static final long serialVersionUID = -8799356878002273414L;
10 |
11 | private ResponseCode code;
12 | private RequestCode requestCode;
13 | private Object extra;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bo/AbstractResource.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bo;
2 |
3 | import java.io.InputStream;
4 | import java.net.URL;
5 |
6 | abstract class AbstractResource {
7 | InputStream loadResource(String path) {
8 | return getClass().getResourceAsStream(path);
9 | }
10 |
11 | URL toUrl(String path) {
12 | return getClass().getResource(path);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/FriendInfoChangedEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | public class FriendInfoChangedEvent {
12 | private Profile newFriendInfo;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/SendChatMessageEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.ChatMessage;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | public class SendChatMessageEvent {
12 | private ChatMessage chatMessage;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/event/ServerStatusChangedEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.event;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | /**
8 | * Occurs when server's status changed.
9 | */
10 | @Data
11 | @NoArgsConstructor
12 | @AllArgsConstructor
13 | public class ServerStatusChangedEvent {
14 | private boolean running;
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/MyAccountInfoReceivedEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | public class MyAccountInfoReceivedEvent {
12 | private Profile myProfile;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bo/ByteTransmission.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bo;
2 |
3 | import java.io.Closeable;
4 | import java.io.IOException;
5 |
6 | /**
7 | * Communicating based on bytes stream.
8 | */
9 | public interface ByteTransmission extends Closeable {
10 | void sendBytes(byte[] in) throws IOException;
11 |
12 | int receiveBytes(byte[] out, int offset, int length) throws IOException;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/ChatMessageReceivedEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.ChatMessage;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | public class ChatMessageReceivedEvent {
12 | private ChatMessage chatMessage;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/model/Worker.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.model;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 |
5 | import java.io.IOException;
6 |
7 | /**
8 | * Communicates with an individual client.
9 | */
10 | public interface Worker {
11 | void start();
12 |
13 | void response(Object obj) throws IOException;
14 |
15 | void setAccount(Profile account);
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bean/UpdatePassword.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bean;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.io.Serializable;
8 |
9 | @Data
10 | @AllArgsConstructor
11 | @NoArgsConstructor
12 | public class UpdatePassword implements Serializable {
13 | private String oldPassword;
14 | private String newPassword;
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/event/FriendListReceivedEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | @Data
11 | @NoArgsConstructor
12 | @AllArgsConstructor
13 | public class FriendListReceivedEvent {
14 | private List friendList;
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/view/MainView.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.view;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.view.BaseView;
4 |
5 | public interface MainView extends BaseView {
6 | String getIp();
7 |
8 | String getPort();
9 |
10 | void setIp(String ip);
11 |
12 | void setPort(int port);
13 |
14 | void setStartButtonText(String text);
15 |
16 | void setStartButtonListener(Runnable listener);
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/view/ConnectionView.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.view;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.view.BaseView;
4 |
5 | public interface ConnectionView extends BaseView {
6 | void setConnectButtonClickListener(Runnable listener);
7 |
8 | String getServerIp();
9 |
10 | String getServerPort();
11 |
12 | void setServerIp(String serverIp);
13 |
14 | void setServerPort(int serverPort);
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/event/LookupWorkerEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import com.blogspot.sontx.chatsocket.server.model.Worker;
5 | import lombok.Data;
6 |
7 | /**
8 | * Finds a running {@link Worker} by an {@link Profile}.
9 | */
10 | @Data
11 | public class LookupWorkerEvent {
12 | private Profile matchedAccount;
13 | private Worker matchedWorker;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/resources/layouts/chat-message-mine.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/model/handler/DoNothingResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.model.handler;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Response;
4 | import com.blogspot.sontx.chatsocket.lib.bo.ObjectTransmission;
5 |
6 | public class DoNothingResponseHandler extends AbstractResponseHandler {
7 | @Override
8 | public void handle(ObjectTransmission transmission, Response response) throws Exception {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/resources/layouts/chat-message-friend.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/view/LoginView.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.view;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.view.BaseView;
4 |
5 | public interface LoginView extends BaseView {
6 | String getUsername();
7 |
8 | String getPassword();
9 |
10 | void setLoginButtonClickListener(Runnable listener);
11 |
12 | void setRegisterButtonClickListener(Runnable listener);
13 |
14 | void setUserName(String loggedUserName);
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/view/ChatView.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.view;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.Callback;
4 | import com.blogspot.sontx.chatsocket.lib.view.BaseView;
5 |
6 | public interface ChatView extends BaseView {
7 | void appendFriendMessage(String message);
8 |
9 | void appendMeMyMessage(String message);
10 |
11 | void setSendButtonClickListener(Callback listener);
12 |
13 | void clearInput();
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/event/AccountInfoChangedEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * Occurs when an account info changed.
10 | */
11 | @Data
12 | @NoArgsConstructor
13 | @AllArgsConstructor
14 | public class AccountInfoChangedEvent {
15 | private Profile profile;
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/utils/StreamUtils.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.utils;
2 |
3 | import java.io.Closeable;
4 | import java.io.IOException;
5 |
6 | public final class StreamUtils {
7 | StreamUtils() {
8 | }
9 |
10 | public static void tryCloseStream(Closeable obj) {
11 | if (obj != null) {
12 | try {
13 | obj.close();
14 | } catch (IOException ignored) {
15 | }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bean/Request.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bean;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.io.Serializable;
8 |
9 | @Data
10 | @AllArgsConstructor
11 | @NoArgsConstructor
12 | public class Request implements Serializable {
13 | private static final long serialVersionUID = 982079171646222501L;
14 |
15 | private RequestCode code;
16 | private Object extra;
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bean/ChatMessage.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bean;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.io.Serializable;
8 |
9 | @Data
10 | @AllArgsConstructor
11 | @NoArgsConstructor
12 | public class ChatMessage implements Serializable {
13 | private static final long serialVersionUID = 5140826547264710686L;
14 |
15 | private String whoId;
16 | private String content;
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bean/LoginInfo.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bean;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.io.Serializable;
8 |
9 | @Data
10 | @AllArgsConstructor
11 | @NoArgsConstructor
12 | public class LoginInfo implements Serializable {
13 | private static final long serialVersionUID = 757708636228559068L;
14 |
15 | private String username;
16 | private String password;
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/service/event/ShowMessageBoxEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.service.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.service.message.MessageType;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | public class ShowMessageBoxEvent {
12 | private String message;
13 | private String caption;
14 | private MessageType type;
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/model/ChattingManager.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.model;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.ChatMessage;
4 | import com.blogspot.sontx.chatsocket.lib.bean.Response;
5 |
6 | /**
7 | * Manages received chat messages.
8 | */
9 | public interface ChattingManager {
10 | void start();
11 |
12 | void stop();
13 |
14 | void processReceivedChatMessage(ChatMessage chatMessage);
15 |
16 | void processSentChatMessage(Response response);
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/model/handler/AbstractResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.model.handler;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.service.AbstractService;
4 | import com.blogspot.sontx.chatsocket.lib.service.message.MessageType;
5 |
6 | abstract class AbstractResponseHandler extends AbstractService implements ResponseHandler {
7 | void showErrorMessage(String message, Object reason) {
8 | postMessageBox(message + ": " + reason, MessageType.Error);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bean/RegisterInfo.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bean;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.io.Serializable;
8 |
9 | @Data
10 | @NoArgsConstructor
11 | @AllArgsConstructor
12 | public class RegisterInfo implements Serializable {
13 | private static final long serialVersionUID = -3586442439987010899L;
14 |
15 | private String username;
16 | private String password;
17 | private String displayName;
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/platform/ClientSwingPlatform.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.platform;
2 |
3 | import com.blogspot.sontx.chatsocket.client.view.swing.SwingViewFactory;
4 | import com.blogspot.sontx.chatsocket.lib.platform.SwingPlatform;
5 | import com.blogspot.sontx.chatsocket.lib.view.ViewFactory;
6 | import lombok.Getter;
7 |
8 | public class ClientSwingPlatform extends SwingPlatform {
9 | @Getter
10 | private final ViewFactory viewFactory;
11 |
12 | public ClientSwingPlatform() {
13 | viewFactory = new SwingViewFactory();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/event/ShutdownWorkerEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.event;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | /**
8 | * Shutdown {@link com.blogspot.sontx.chatsocket.server.model.Worker} command.
9 | * All {@link com.blogspot.sontx.chatsocket.server.model.Worker} that have the corresponding serverSession
10 | * should shutdown.
11 | */
12 | @Data
13 | @NoArgsConstructor
14 | @AllArgsConstructor
15 | public class ShutdownWorkerEvent {
16 | private int serverSession;
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/platform/ServerSwingPlatform.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.platform;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.platform.SwingPlatform;
4 | import com.blogspot.sontx.chatsocket.lib.view.ViewFactory;
5 | import com.blogspot.sontx.chatsocket.server.view.swing.SwingViewFactory;
6 | import lombok.Getter;
7 |
8 | public class ServerSwingPlatform extends SwingPlatform {
9 | @Getter
10 | private final ViewFactory viewFactory;
11 |
12 | public ServerSwingPlatform() {
13 | viewFactory = new SwingViewFactory();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/view/WindowUtils.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.view;
2 |
3 | import javax.swing.*;
4 |
5 | public final class WindowUtils {
6 |
7 | private WindowUtils() {
8 | }
9 |
10 | public static void setSystemLookAndFeel() {
11 | try {
12 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
13 | } catch (ClassNotFoundException
14 | | InstantiationException
15 | | IllegalAccessException
16 | | UnsupportedLookAndFeelException ignored) {
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/model/handler/AccountInfoRequestHandler.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.model.handler;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Response;
4 | import com.blogspot.sontx.chatsocket.server.event.RequestReceivedEvent;
5 |
6 | /**
7 | * Handles account info request from the client.
8 | */
9 | class AccountInfoRequestHandler extends AbstractRequestHandler {
10 | @Override
11 | Response handleWithAuthenticated(RequestReceivedEvent event) throws Exception {
12 | return okResponse(event.getProfile(), event.getRequest().getCode());
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/event/ShutdownServerEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.event;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | /**
8 | * Shutdown {@link com.blogspot.sontx.chatsocket.server.model.Server} command.
9 | * All {@link com.blogspot.sontx.chatsocket.server.model.Server} that have corresponding sessionId
10 | * should shutdown.
11 | */
12 | @Data
13 | @NoArgsConstructor
14 | @AllArgsConstructor
15 | public class ShutdownServerEvent {
16 | public static final int ALL = -1;
17 |
18 | private int sessionId;
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/platform/Platform.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.platform;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.settings.SettingsLoader;
4 | import com.blogspot.sontx.chatsocket.lib.thread.ThreadInvoker;
5 | import com.blogspot.sontx.chatsocket.lib.view.ViewFactory;
6 |
7 | public interface Platform {
8 | ViewFactory getViewFactory();
9 |
10 | ThreadInvoker getThreadInvoker();
11 |
12 | SettingsLoader getSettings();
13 |
14 | void attach(Object service);
15 |
16 | void detach(Object service);
17 |
18 | void postEvent(Object event);
19 |
20 | void exit();
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/view/TwoLineJLabel.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.view;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.apache.commons.text.StringEscapeUtils;
5 |
6 | import javax.swing.*;
7 |
8 | public class TwoLineJLabel extends JLabel {
9 | protected void setText(String line1, String line2) {
10 | String escapedLine1 = StringUtils.isEmpty(line1) ? "" : StringEscapeUtils.escapeHtml3(line1);
11 | String escapedLine2 = StringUtils.isEmpty(line2) ? "" : StringEscapeUtils.escapeHtml3(line2);
12 | setText(String.format("%s
%s", escapedLine1, escapedLine2));
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/event/RequestReceivedEvent.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.event;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import com.blogspot.sontx.chatsocket.lib.bean.Request;
5 | import com.blogspot.sontx.chatsocket.server.model.Worker;
6 | import lombok.AllArgsConstructor;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | /**
11 | * Occurs when received a request from a client.
12 | */
13 | @Data
14 | @NoArgsConstructor
15 | @AllArgsConstructor
16 | public class RequestReceivedEvent {
17 | private Request request;
18 | private Profile profile;
19 | private Worker sender;
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/model/handler/PasswordResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.model.handler;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Response;
4 | import com.blogspot.sontx.chatsocket.lib.bean.ResponseCode;
5 | import com.blogspot.sontx.chatsocket.lib.bo.ObjectTransmission;
6 |
7 | public class PasswordResponseHandler extends AbstractResponseHandler {
8 | @Override
9 | public void handle(ObjectTransmission transmission, Response response) throws Exception {
10 | if (response.getCode() == ResponseCode.Fail) {
11 | showErrorMessage("Can not change password", response.getExtra());
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/service/BackgroundService.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.service;
2 |
3 | public abstract class BackgroundService extends AbstractService implements Runnable {
4 | private Thread thread;
5 |
6 | @Override
7 | public synchronized void start() {
8 | if (isStarted()) return;
9 | super.start();
10 | thread = new Thread(this);
11 | thread.setDaemon(true);
12 | thread.start();
13 | }
14 |
15 | @Override
16 | public synchronized void stop() {
17 | if (!isStarted()) return;
18 | super.stop();
19 | thread.interrupt();
20 | }
21 |
22 | public abstract void run();
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/model/account/AccountStorage.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.model.account;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 |
5 | import java.util.List;
6 | import java.util.Optional;
7 |
8 | /**
9 | * Reads/writes accounts data from/to storage.
10 | */
11 | public interface AccountStorage {
12 | Optional findById(String id);
13 |
14 | Optional findByUserName(String username);
15 |
16 | Account add(Account account);
17 |
18 | List findAll();
19 |
20 | void updateDetail(String accountId, Profile profile);
21 |
22 | void updatePasswordHash(String accountId, String passwordHash);
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/view/ProfileView.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.view;
2 |
3 | import com.blogspot.sontx.chatsocket.client.model.UserProfile;
4 | import com.blogspot.sontx.chatsocket.lib.Callback;
5 | import com.blogspot.sontx.chatsocket.lib.bean.UpdatePassword;
6 | import com.blogspot.sontx.chatsocket.lib.view.BaseView;
7 |
8 | public interface ProfileView extends BaseView {
9 | void setChangeDisplayNameButtonClickListener(Callback listener);
10 |
11 | void setChangeStatusButtonClickListener(Callback listener);
12 |
13 | void setChangePasswordButtonClickListener(Callback listener);
14 |
15 | void setProfile(UserProfile userProfile);
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bo/LayoutsResource.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bo;
2 |
3 | import java.io.InputStream;
4 | import java.net.URL;
5 |
6 | public class LayoutsResource extends AbstractResource {
7 | private static LayoutsResource instance;
8 |
9 | public synchronized static LayoutsResource getInstance() {
10 | if (instance == null)
11 | instance = new LayoutsResource();
12 | return instance;
13 | }
14 |
15 | public InputStream load(String layoutName) {
16 | return loadResource("/layouts/" + layoutName);
17 | }
18 |
19 | public URL getResource(String layoutName) {
20 | return toUrl("/layouts/" + layoutName);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/view/swing/SwingViewFactory.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.view.swing;
2 |
3 | import com.blogspot.sontx.chatsocket.client.view.*;
4 | import com.blogspot.sontx.chatsocket.lib.view.AbstractViewFactory;
5 |
6 | public class SwingViewFactory extends AbstractViewFactory {
7 | public SwingViewFactory() {
8 | register(ChatView.class, ChatWindow::new);
9 | register(ConnectionView.class, ConnectionWindow::new);
10 | register(FriendListView.class, FriendListWindow::new);
11 | register(LoginView.class, LoginWindow::new);
12 | register(ProfileView.class, ProfileWindow::new);
13 | register(RegisterView.class, RegisterWindow::new);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/view/FriendListView.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.view;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.Callback;
4 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
5 | import com.blogspot.sontx.chatsocket.lib.view.BaseView;
6 |
7 | import java.util.List;
8 |
9 | public interface FriendListView extends BaseView {
10 | void setMyInfoButtonClickListener(Runnable listener);
11 |
12 | void setFriendButtonClickListener(Callback listener);
13 |
14 | void setFriendList(List friendProfileList);
15 |
16 | void setMyAccountInfo(Profile profile);
17 |
18 | void updateFriend(Profile friendInfo);
19 |
20 | void addNewFriend(Profile newFriendInfo);
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/thread/JavaFxThreadInvoker.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.thread;
2 |
3 | import com.sun.javafx.application.PlatformImpl;
4 | import javafx.application.Platform;
5 | import lombok.extern.log4j.Log4j;
6 |
7 | @Log4j
8 | public class JavaFxThreadInvoker extends AbstractThreadInvoker {
9 | @Override
10 | public void invokeLater(Runnable runnable) {
11 | if (PlatformImpl.isFxApplicationThread()) {
12 | executeAsync(() -> invokeLater(runnable));
13 | } else {
14 | Platform.runLater(runnable);
15 | }
16 | }
17 |
18 | @Override
19 | public void invokeAndWait(Runnable runnable) {
20 | PlatformImpl.runAndWait(runnable);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/view/javafx/JavaFxViewFactory.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.view.javafx;
2 |
3 | import com.blogspot.sontx.chatsocket.client.view.*;
4 | import com.blogspot.sontx.chatsocket.lib.view.AbstractViewFactory;
5 |
6 | public class JavaFxViewFactory extends AbstractViewFactory {
7 |
8 | public JavaFxViewFactory() {
9 | register(ChatView.class, ChatWindow::new);
10 | register(ConnectionView.class, ConnectionWindow::new);
11 | register(FriendListView.class, FriendListWindow::new);
12 | register(LoginView.class, LoginWindow::new);
13 | register(ProfileView.class, ProfileWindow::new);
14 | register(RegisterView.class, RegisterWindow::new);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/service/MessageBoxService.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.service;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.service.event.ShowMessageBoxEvent;
4 | import com.blogspot.sontx.chatsocket.lib.service.message.MessageBox;
5 | import com.google.common.eventbus.Subscribe;
6 |
7 | public class MessageBoxService extends AbstractService {
8 | private final MessageBox messageBox;
9 |
10 | public MessageBoxService(MessageBox messageBox) {
11 | this.messageBox = messageBox;
12 | }
13 |
14 | @Subscribe
15 | public void onShowMessageBox(ShowMessageBoxEvent event) {
16 | runOnUiThread(() -> messageBox.show(event.getCaption(), event.getMessage(), event.getType()));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | # Root logger option
2 | log4j.rootLogger=DEBUG, stdout, file
3 |
4 | # Redirect log messages to console
5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
6 | log4j.appender.stdout.Target=System.out
7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
8 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
9 |
10 | # Redirect log messages to a log file, support file rolling.
11 | log4j.appender.file=org.apache.log4j.RollingFileAppender
12 | log4j.appender.file.File=logs\\app.log
13 | log4j.appender.file.MaxFileSize=5MB
14 | log4j.appender.file.MaxBackupIndex=10
15 | log4j.appender.file.layout=org.apache.log4j.PatternLayout
16 | log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/platform/SwingPlatform.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.platform;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.service.MessageBoxService;
4 | import com.blogspot.sontx.chatsocket.lib.service.message.SwingMessageBox;
5 | import com.blogspot.sontx.chatsocket.lib.thread.SwingThreadInvoker;
6 | import com.blogspot.sontx.chatsocket.lib.view.WindowUtils;
7 |
8 | public abstract class SwingPlatform extends AbstractPlatform {
9 | protected SwingPlatform() {
10 | super(new SwingThreadInvoker());
11 | WindowUtils.setSystemLookAndFeel();
12 | MessageBoxService messageBoxService = new MessageBoxService(new SwingMessageBox());
13 | messageBoxService.setPlatform(this);
14 | messageBoxService.start();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/model/account/AccountManager.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.model.account;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
4 | import com.blogspot.sontx.chatsocket.lib.bean.LoginInfo;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * Manages accounts.
10 | */
11 | public interface AccountManager {
12 |
13 | List getAllAccounts();
14 |
15 | Profile findAccountByLoginInfo(LoginInfo loginInfo);
16 |
17 | boolean setPasswordHash(String accountId, String currentPasswordHash, String newPasswordHash);
18 |
19 | Profile findAccountByUserName(String username);
20 |
21 | Profile addAccount(String username, String passwordHash, String displayName);
22 |
23 | void updateDetail(Profile profile);
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/bean/Profile.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.bean;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnore;
4 | import lombok.Data;
5 | import lombok.EqualsAndHashCode;
6 |
7 | import java.io.Serializable;
8 |
9 | @Data
10 | @EqualsAndHashCode(of = "id")
11 | public class Profile implements Serializable {
12 | public static final int STATE_ONLINE = 0;
13 | public static final int STATE_OFFLINE = 1;
14 | private static final long serialVersionUID = -4193811689167914857L;
15 | @JsonIgnore
16 | private String id;
17 |
18 | private String displayName;
19 | private String status;
20 |
21 | @JsonIgnore
22 | private int state;
23 |
24 | @JsonIgnore
25 | public boolean isOnline() {
26 | return state == STATE_ONLINE;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/server/view/swing/SwingViewFactory.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.server.view.swing;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.view.AbstractViewFactory;
4 | import com.blogspot.sontx.chatsocket.server.view.LogView;
5 | import com.blogspot.sontx.chatsocket.server.view.MainView;
6 |
7 | public class SwingViewFactory extends AbstractViewFactory {
8 | private MainWindow mainWindow;
9 |
10 | public SwingViewFactory() {
11 | register(MainView.class, this::createMainWindowIfNecessary);
12 | register(LogView.class, this::createMainWindowIfNecessary);
13 | }
14 |
15 | private MainWindow createMainWindowIfNecessary() {
16 | if (this.mainWindow == null)
17 | mainWindow = new MainWindow();
18 | return mainWindow;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/client/model/handler/FriendInfoResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.client.model.handler;
2 |
3 | import com.blogspot.sontx.chatsocket.client.event.FriendInfoChangedEvent;
4 | import com.blogspot.sontx.chatsocket.lib.bean.Profile;
5 | import com.blogspot.sontx.chatsocket.lib.bean.Response;
6 | import com.blogspot.sontx.chatsocket.lib.bean.ResponseCode;
7 | import com.blogspot.sontx.chatsocket.lib.bo.ObjectTransmission;
8 |
9 | public class FriendInfoResponseHandler extends AbstractResponseHandler {
10 | @Override
11 | public void handle(ObjectTransmission transmission, Response response) throws Exception {
12 | if (response.getCode() == ResponseCode.OK) {
13 | post(new FriendInfoChangedEvent((Profile) response.getExtra()));
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/platform/JavaFxPlatform.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.platform;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.service.MessageBoxService;
4 | import com.blogspot.sontx.chatsocket.lib.service.message.JavaFxMessageBox;
5 | import com.blogspot.sontx.chatsocket.lib.thread.JavaFxThreadInvoker;
6 |
7 | public abstract class JavaFxPlatform extends AbstractPlatform {
8 | protected JavaFxPlatform() {
9 | super(new JavaFxThreadInvoker());
10 | MessageBoxService messageBoxService = new MessageBoxService(new JavaFxMessageBox());
11 | messageBoxService.setPlatform(this);
12 | messageBoxService.start();
13 | }
14 |
15 | @Override
16 | public void exit() {
17 | javafx.application.Platform.exit();
18 | super.exit();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/resources/layouts/password-dialog.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/thread/AbstractThreadInvoker.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.thread;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.Function;
4 |
5 | import java.util.concurrent.ExecutorService;
6 | import java.util.concurrent.Executors;
7 |
8 | public abstract class AbstractThreadInvoker implements ThreadInvoker {
9 | private final ExecutorService executorService = Executors.newCachedThreadPool();
10 |
11 | @Override
12 | public void executeAsync(Runnable callback) {
13 | executorService.execute(callback);
14 | }
15 |
16 | @Override
17 | @SuppressWarnings("unchecked")
18 | public T invokeWithResult(Function func) {
19 | Object[] result = new Object[1];
20 | invokeAndWait(() -> result[0] = func.call());
21 | return (T) result[0];
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/AbstractPresenter.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.event.AppShutdownEvent;
4 | import com.blogspot.sontx.chatsocket.lib.service.AbstractService;
5 | import com.blogspot.sontx.chatsocket.lib.view.BaseView;
6 |
7 | public abstract class AbstractPresenter extends AbstractService implements Presenter {
8 | protected final TView view;
9 |
10 | protected AbstractPresenter(TView view) {
11 | this.view = view;
12 | wireUpViewEvents();
13 | }
14 |
15 | protected void wireUpViewEvents() {
16 | view.setOnClosingListener(this::onUserClosesView);
17 | }
18 |
19 | protected void onUserClosesView() {
20 | if (view.isMainWindow())
21 | post(new AppShutdownEvent());
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/blogspot/sontx/chatsocket/lib/view/AbstractViewFactory.java:
--------------------------------------------------------------------------------
1 | package com.blogspot.sontx.chatsocket.lib.view;
2 |
3 | import com.blogspot.sontx.chatsocket.lib.Function;
4 | import com.blogspot.sontx.chatsocket.lib.NotRegisteredException;
5 |
6 | import java.util.HashMap;
7 | import java.util.Map;
8 |
9 | public abstract class AbstractViewFactory implements ViewFactory {
10 | private final Map> views = new HashMap<>();
11 |
12 | protected void register(Class viewType, Function
24 | */
25 | @Log4j
26 | class Bootstrap {
27 | private Options options;
28 |
29 | Bootstrap() {
30 | initializeOptions();
31 | }
32 |
33 | private void initializeOptions() {
34 | options = new Options();
35 | options.addOption("h", "help", false, "Show help.");
36 | options.addOption("m", "mode", true, "The app should be run as client/server mode.");
37 | options.addOption("ui", "uistyle", true, "UI style will be shown (swing/javafx)");
38 | }
39 |
40 | void boot(String[] args) {
41 | CommandLine commandLine = parseArgs(args);
42 | if (commandLine == null || commandLine.hasOption("h")) {
43 | showHelp();
44 | } else if (commandLine.hasOption("m")) {
45 | String mode = commandLine.getOptionValue("m");
46 | if ("client".equals(mode))
47 | startClient(commandLine.getOptionValue("ui"));
48 | else if ("server".equals(mode))
49 | startServer(commandLine.getOptionValue("ui"));
50 | else
51 | showHelp();
52 | } else {
53 | askUser();
54 | }
55 | }
56 |
57 | private void askUser() {
58 | System.out.print("Working mode was not supplied, please enter your mode (client/server): ");
59 | Scanner scanner = new Scanner(System.in);
60 | String mode = scanner.nextLine();
61 | if (mode.equals("client"))
62 | startClient(null);
63 | else if (mode.equals("server"))
64 | startServer(null);
65 | }
66 |
67 | private void startClient(String uiStyle) {
68 | log.info("Starting app as client");
69 | new AppClientImpl().start("swing".equals(uiStyle) ? new ClientSwingPlatform() : new ClientJavaFxPlatform());
70 | }
71 |
72 | private void startServer(String uiStyle) {
73 | log.info("Starting app as server");
74 | new AppServerImpl().start("swing".equals(uiStyle) ? new ServerSwingPlatform() : new ServerJavaFxPlatform());
75 | }
76 |
77 | private CommandLine parseArgs(String[] args) {
78 | CommandLineParser parser = new DefaultParser();
79 | try {
80 | return parser.parse(options, args);
81 | } catch (ParseException e) {
82 | log.error("Wrong app arguments", e);
83 | return null;
84 | }
85 | }
86 |
87 | private void showHelp() {
88 | HelpFormatter formatter = new HelpFormatter();
89 | formatter.printHelp(AppConfig.getDefault().getAppName(), options);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.blogspot.sontx
8 | chatsocket
9 | 1.0-SNAPSHOT
10 |
11 |
12 | UTF-8
13 |
14 |
15 |
16 |
17 | com.fasterxml.jackson.core
18 | jackson-core
19 | 2.9.5
20 |
21 |
22 | com.fasterxml.jackson.core
23 | jackson-databind
24 | 2.9.10.1
25 |
26 |
27 | org.json
28 | json
29 | 20180130
30 |
31 |
32 | org.apache.commons
33 | commons-lang3
34 | 3.7
35 |
36 |
37 | org.apache.commons
38 | commons-text
39 | 1.4
40 |
41 |
42 | commons-cli
43 | commons-cli
44 | 1.4
45 |
46 |
47 | org.projectlombok
48 | lombok
49 | 1.18.0
50 | provided
51 |
52 |
53 | log4j
54 | log4j
55 | 1.2.17
56 |
57 |
58 | com.google.guava
59 | guava
60 | 28.2-jre
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | org.codehaus.mojo
69 | exec-maven-plugin
70 | 1.6.0
71 |
72 |
73 |
74 | java
75 |
76 |
77 |
78 |
79 | com.blogspot.sontx.chatsocket.Program
80 |
81 |
82 |
83 | maven-compiler-plugin
84 |
85 | 1.8
86 | 1.8
87 |
88 |
89 |
90 | maven-assembly-plugin
91 |
92 |
93 |
94 | com.blogspot.sontx.chatsocket.Program
95 |
96 |
97 |
98 | jar-with-dependencies
99 |
100 |
101 |
102 |
103 | make-assembly
104 | package
105 |
106 | single
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------