diff --git a/droidstomplib/.gitignore b/droidstomplib/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/droidstomplib/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/droidstomplib/build.gradle b/droidstomplib/build.gradle
new file mode 100644
index 0000000..4ea1842
--- /dev/null
+++ b/droidstomplib/build.gradle
@@ -0,0 +1,35 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion 28
+
+
+
+ defaultConfig {
+ minSdkVersion 16
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ implementation 'com.squareup.okhttp3:okhttp:3.12.0'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+}
diff --git a/droidstomplib/proguard-rules.pro b/droidstomplib/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/droidstomplib/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/droidstomplib/src/androidTest/java/com/github/dadekuma/droidstomplib/ExampleInstrumentedTest.java b/droidstomplib/src/androidTest/java/com/github/dadekuma/droidstomplib/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..aeafdc8
--- /dev/null
+++ b/droidstomplib/src/androidTest/java/com/github/dadekuma/droidstomplib/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.github.dadekuma.droidstomplib;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.github.dadekuma.droidstomplib.test", appContext.getPackageName());
+ }
+}
diff --git a/droidstomplib/src/main/AndroidManifest.xml b/droidstomplib/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..f3ea17c
--- /dev/null
+++ b/droidstomplib/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/IConnectionProvider.java b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/IConnectionProvider.java
new file mode 100644
index 0000000..fe63f7c
--- /dev/null
+++ b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/IConnectionProvider.java
@@ -0,0 +1,13 @@
+package com.github.dadekuma.droidstomplib.connection;
+
+import com.github.dadekuma.droidstomplib.payload.HttpHeader;
+
+import java.util.Collection;
+
+public interface IConnectionProvider {
+ void connect(String stompEndpoint, Collection headers);
+ void send(String payload);
+ void setStompCallback(IStompCallback stompCallback);
+ boolean isConnected();
+ boolean isConnecting();
+}
diff --git a/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/IStompCallback.java b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/IStompCallback.java
new file mode 100644
index 0000000..1082634
--- /dev/null
+++ b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/IStompCallback.java
@@ -0,0 +1,10 @@
+package com.github.dadekuma.droidstomplib.connection;
+
+public interface IStompCallback {
+ void onConnectionOpened();
+ void onConnectionClosed(int code, String reason);
+ void onResponseReceived(String response);
+ void onMessageReceived(String topic, Long subscriptionId, String message);
+ boolean isConnected();
+ boolean isConnecting();
+}
diff --git a/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/IStompClient.java b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/IStompClient.java
new file mode 100644
index 0000000..5a6dc66
--- /dev/null
+++ b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/IStompClient.java
@@ -0,0 +1,18 @@
+package com.github.dadekuma.droidstomplib.connection;
+
+import com.github.dadekuma.droidstomplib.payload.HttpHeader;
+
+import java.util.Collection;
+
+public interface IStompClient {
+ void setStompCallback(IStompCallback stompCallback);
+ void connect(String stompEndpoint);
+ void connect(String stompEndpoint, Collection headers);
+ void send(String stompDestination, String message);
+ void sendJson(String stompDestination, String jsonMessage);
+ void subscribe(String topic);
+ void unsubscribe(String topic);
+ void disconnect();
+ boolean isConnected();
+ boolean isConnecting();
+}
diff --git a/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/OkHttpConnectionProvider.java b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/OkHttpConnectionProvider.java
new file mode 100644
index 0000000..132d548
--- /dev/null
+++ b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/OkHttpConnectionProvider.java
@@ -0,0 +1,82 @@
+package com.github.dadekuma.droidstomplib.connection;
+
+import com.github.dadekuma.droidstomplib.payload.HttpHeader;
+
+import java.util.Collection;
+
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import okhttp3.WebSocket;
+import okhttp3.WebSocketListener;
+import okio.ByteString;
+
+
+public class OkHttpConnectionProvider implements IConnectionProvider {
+ private OkHttpClient okHttpClient;
+ private WebSocket webSocket;
+ private IStompCallback stompCallback;
+
+ public OkHttpConnectionProvider() {
+ this(new OkHttpClient());
+ }
+
+ public OkHttpConnectionProvider(OkHttpClient okHttpClient) {
+ this.okHttpClient = okHttpClient;
+ }
+
+
+ @Override
+ public void connect(String stompEndpoint, Collection headers) {
+ Request.Builder requestBuilder = new Request.Builder().url(stompEndpoint);
+ //add all http headers that you need to the request.
+ for (HttpHeader h : headers) {
+ requestBuilder.addHeader(h.getName(), h.getValue());
+ }
+ Request request = requestBuilder.build();
+
+ webSocket = okHttpClient.newWebSocket(request, new WebSocketListener() {
+ @Override
+ public void onOpen(WebSocket webSocket, Response response) {
+ if(stompCallback == null) return;
+ stompCallback.onConnectionOpened();
+ }
+
+ @Override
+ public void onMessage(WebSocket webSocket, ByteString bytes) {
+ }
+
+ @Override
+ public void onClosed(WebSocket webSocket, int code, String reason) {
+ if(stompCallback == null) return;
+ stompCallback.onConnectionClosed(code, reason);
+ }
+
+ @Override
+ public void onMessage(WebSocket webSocket, String text) {
+ if(stompCallback == null) return;
+ stompCallback.onResponseReceived(text);
+ }
+ });
+ }
+
+ @Override
+ public void send(String payload) {
+ webSocket.send(payload);
+ }
+
+ @Override
+ public void setStompCallback(IStompCallback stompCallback) {
+ this.stompCallback = stompCallback;
+ }
+
+ @Override
+ public boolean isConnected() {
+ return stompCallback.isConnected();
+ }
+
+ @Override
+ public boolean isConnecting() {
+ return stompCallback.isConnecting();
+ }
+}
diff --git a/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/StompCallback.java b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/StompCallback.java
new file mode 100644
index 0000000..bf13755
--- /dev/null
+++ b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/StompCallback.java
@@ -0,0 +1,55 @@
+package com.github.dadekuma.droidstomplib.connection;
+
+import com.github.dadekuma.droidstomplib.enums.StompHeaderName;
+import com.github.dadekuma.droidstomplib.payload.StompFrame;
+import com.github.dadekuma.droidstomplib.payload.StompParser;
+
+import java.util.Map;
+
+public abstract class StompCallback implements IStompCallback{
+ private boolean isConnected, isConnecting;
+
+ @Override
+ public void onConnectionOpened() {
+ isConnecting = true;
+ }
+
+ @Override
+ public void onConnectionClosed(int code, String reason) {
+ isConnected = isConnecting = false;
+ }
+
+ @Override
+ public void onResponseReceived(String response) {
+ StompFrame stompFrame = StompParser.parse(response);
+ switch (stompFrame.getStompCommand()){
+ case CONNECTED:
+ isConnected = true;
+ break;
+ case MESSAGE:
+ handleSubscriptionMessage(stompFrame);
+ break;
+ }
+ }
+
+ private void handleSubscriptionMessage(StompFrame stompFrame){
+ Map headers = stompFrame.getStompHeaders();
+ String topic = headers.get(StompHeaderName.DESTINATION);
+ long subscriptionId = Long.parseLong(headers.get(StompHeaderName.SUBSCRIPTION));
+ String body = stompFrame.getStompBody();
+ onMessageReceived(topic, subscriptionId, body);
+ }
+
+ @Override
+ public abstract void onMessageReceived(String topic, Long subscriptionId, String message);
+
+ @Override
+ public boolean isConnected() {
+ return isConnected;
+ }
+
+ @Override
+ public boolean isConnecting() {
+ return isConnecting;
+ }
+}
diff --git a/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/StompClient.java b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/StompClient.java
new file mode 100644
index 0000000..a3c23a7
--- /dev/null
+++ b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/connection/StompClient.java
@@ -0,0 +1,118 @@
+package com.github.dadekuma.droidstomplib.connection;
+
+import android.util.Log;
+
+import com.github.dadekuma.droidstomplib.enums.StompCommandName;
+import com.github.dadekuma.droidstomplib.enums.StompHeaderName;
+import com.github.dadekuma.droidstomplib.payload.HttpHeader;
+import com.github.dadekuma.droidstomplib.payload.StompFrame;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+public class StompClient implements IStompClient {
+ private Map subscriptions;
+ private long subscriptionId;
+ private IConnectionProvider connectionProvider;
+
+ public StompClient() {
+ this(new OkHttpConnectionProvider());
+ }
+
+ public StompClient(IConnectionProvider connectionProvider) {
+ this.connectionProvider = connectionProvider;
+ subscriptions = new HashMap<>();
+ }
+
+ @Override
+ public void connect(String stompEndpoint) {
+ connect(stompEndpoint, new LinkedList());
+ }
+
+ @Override
+ public void connect(String stompEndpoint, Collection headers) {
+ connectionProvider.connect(stompEndpoint, headers);
+ StompFrame stompFrame = new StompFrame();
+ stompFrame.addStompCommand(StompCommandName.CONNECT)
+ .addStompHeader(StompHeaderName.ACCEPT_VERSION, "1.0,1.1,2.0")
+ .addStompHeader(StompHeaderName.HOST, "stomp.github.org");
+ connectionProvider.send(stompFrame.build());
+ }
+
+ @Override
+ public void send(String stompDestination, String message) {
+ StompFrame stompFrame = new StompFrame();
+ stompFrame.addStompCommand(StompCommandName.SEND)
+ .addStompHeader(StompHeaderName.DESTINATION, stompDestination)
+ .addStompHeader(StompHeaderName.CONTENT_TYPE, "text/plain")
+ .addBody(message);
+ connectionProvider.send(stompFrame.build());
+ }
+
+ @Override
+ public void sendJson(String stompDestination, String jsonMessage) {
+ StompFrame stompFrame = new StompFrame();
+ stompFrame.addStompCommand(StompCommandName.SEND)
+ .addStompHeader(StompHeaderName.DESTINATION, stompDestination)
+ .addStompHeader(StompHeaderName.CONTENT_TYPE, "application/json;charset=utf-8")
+ .addBody(jsonMessage);
+ connectionProvider.send(stompFrame.build());
+ }
+
+ @Override
+ public void subscribe(String topic) {
+ subscriptionId += 1;
+ StompFrame stompFrame = new StompFrame();
+ stompFrame.addStompCommand(StompCommandName.SUBSCRIBE)
+ .addStompHeader(StompHeaderName.ID, String.valueOf(subscriptionId))
+ .addStompHeader(StompHeaderName.DESTINATION, topic)
+ .addStompHeader(StompHeaderName.ACK, "auto");
+ connectionProvider.send(stompFrame.build());
+ subscriptions.put(topic, subscriptionId);
+ }
+
+ @Override
+ public void unsubscribe(String topic) {
+ if (!subscriptions.containsKey(topic)) {
+ Log.e("SUB_NOT_FOUND", "Subscription doesn't exist");
+ return;
+ }
+ Long unsubscribeId = subscriptions.get(topic);
+ StompFrame stompFrame = new StompFrame();
+ stompFrame.addStompCommand(StompCommandName.UNSUBSCRIBE)
+ .addStompHeader(StompHeaderName.ID, String.valueOf(unsubscribeId));
+ connectionProvider.send(stompFrame.build());
+ }
+
+ @Override
+ public void disconnect() {
+ unsubscribeAll();
+ StompFrame stompFrame = new StompFrame();
+ stompFrame.addStompCommand(StompCommandName.DISCONNECT)
+ .addStompHeader(StompHeaderName.RECEIPT, String.valueOf(subscriptionId));
+ connectionProvider.send(stompFrame.build());
+ }
+
+ public void unsubscribeAll() {
+ for (String topic : subscriptions.keySet()) {
+ unsubscribe(topic);
+ }
+ }
+
+ @Override
+ public void setStompCallback(IStompCallback stompCallback){
+ connectionProvider.setStompCallback(stompCallback);
+ }
+
+ @Override
+ public boolean isConnected() {
+ return connectionProvider.isConnected();
+ }
+
+ @Override
+ public boolean isConnecting() {
+ return connectionProvider.isConnecting();
+ }
+}
diff --git a/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/enums/StompCommandName.java b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/enums/StompCommandName.java
new file mode 100644
index 0000000..8d4807e
--- /dev/null
+++ b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/enums/StompCommandName.java
@@ -0,0 +1,36 @@
+package com.github.dadekuma.droidstomplib.enums;
+
+public enum StompCommandName {
+ CONNECT("CONNECT"),
+ CONNECTED("CONNECTED"),
+ SEND("SEND"),
+ SUBSCRIBE("SUBSCRIBE"),
+ UNSUBSCRIBE("UNSUBSCRIBE"),
+ BEGIN("BEGIN"),
+ COMMIT("COMMIT"),
+ ABORT("ABORT"),
+ ACK("ACK"),
+ NACK("NACK"),
+ DISCONNECT("DISCONNECT"),
+ MESSAGE("MESSAGE"),
+ RECEIPT("RECEIPT"),
+ ERROR("ERROR")
+ ;
+
+ String command;
+ StompCommandName(String command) {
+ this.command = command;
+ }
+
+ @Override
+ public String toString() {
+ return command;
+ }
+
+ public static StompCommandName getEnum(String stompCommandName) {
+ for (StompCommandName h : StompCommandName.values()) {
+ if (h.toString().equals(stompCommandName)) return h;
+ }
+ throw new IllegalArgumentException("StompCommandName not found.");
+ }
+}
diff --git a/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/enums/StompHeaderName.java b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/enums/StompHeaderName.java
new file mode 100644
index 0000000..9e0e94b
--- /dev/null
+++ b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/enums/StompHeaderName.java
@@ -0,0 +1,38 @@
+package com.github.dadekuma.droidstomplib.enums;
+
+public enum StompHeaderName {
+ ACCEPT_VERSION("accept-version"),
+ CONTENT_LENGTH("content-length"),
+ CONTENT_TYPE("content-type"),
+ ID("id"),
+ ACK("ack"),
+ HOST("host"),
+ RECEIPT("receipt"),
+ DESTINATION("destination"),
+ SERVER("server"),
+ SESSION("session"),
+ SUBSCRIPTION("subscription"),
+ MESSAGE_ID("message-id"),
+ RECEIPT_ID("receipt-id"),
+ HEART_BEAT("heart-beat"),
+ MESSAGE("message"),
+ VERSION("version"),
+ ;
+
+ private String header;
+ StompHeaderName(String header) {
+ this.header = header;
+ }
+
+ @Override
+ public String toString() {
+ return header;
+ }
+
+ public static StompHeaderName getEnum(String stompHeaderName) {
+ for (StompHeaderName h : StompHeaderName.values()) {
+ if (h.toString().equals(stompHeaderName)) return h;
+ }
+ throw new IllegalArgumentException("StompHeaderName not found.");
+ }
+}
diff --git a/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/enums/StompSymbolName.java b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/enums/StompSymbolName.java
new file mode 100644
index 0000000..4ee04e7
--- /dev/null
+++ b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/enums/StompSymbolName.java
@@ -0,0 +1,17 @@
+package com.github.dadekuma.droidstomplib.enums;
+
+public enum StompSymbolName {
+ SEPARATOR(":"),
+ NEWLINE("\n"),
+ TERMINATOR("\u0000");
+
+ private String symbol;
+ StompSymbolName(String symbol) {
+ this.symbol = symbol;
+ }
+
+ @Override
+ public String toString() {
+ return symbol;
+ }
+}
diff --git a/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/payload/HttpHeader.java b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/payload/HttpHeader.java
new file mode 100644
index 0000000..07e2720
--- /dev/null
+++ b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/payload/HttpHeader.java
@@ -0,0 +1,19 @@
+package com.github.dadekuma.droidstomplib.payload;
+
+public class HttpHeader {
+ private String name;
+ private String value;
+
+ public HttpHeader(String name, String value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/payload/StompFrame.java b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/payload/StompFrame.java
new file mode 100644
index 0000000..ea6f5e7
--- /dev/null
+++ b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/payload/StompFrame.java
@@ -0,0 +1,69 @@
+package com.github.dadekuma.droidstomplib.payload;
+
+import android.support.annotation.NonNull;
+
+import com.github.dadekuma.droidstomplib.enums.StompCommandName;
+import com.github.dadekuma.droidstomplib.enums.StompHeaderName;
+import com.github.dadekuma.droidstomplib.enums.StompSymbolName;
+
+import java.io.Serializable;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class StompFrame {
+ private Map stompHeaders;
+ private StompCommandName stompCommand;
+ private String stompBody;
+
+ public StompFrame() {
+ stompHeaders = new LinkedHashMap<>();
+ }
+
+ public StompFrame addStompCommand(@NonNull StompCommandName command){
+ this.stompCommand = command;
+ return this;
+ }
+
+ public StompFrame addStompHeader(@NonNull StompHeaderName header, @NonNull String value){
+ stompHeaders.put(header, value);
+ return this;
+ }
+
+ public StompFrame addBody(Serializable body){
+ stompBody = body.toString();
+ return this;
+ }
+
+ public String build(){
+ String newline = StompSymbolName.NEWLINE.toString();
+ String separator = StompSymbolName.SEPARATOR.toString();
+ String terminator = StompSymbolName.TERMINATOR.toString();
+
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append(stompCommand).append(newline);
+
+ for(StompHeaderName headerName : stompHeaders.keySet()){
+ String name = headerName.toString();
+ String value = stompHeaders.get(headerName);
+ stringBuilder.append(name).append(separator).append(value).append(newline);
+ }
+ stringBuilder.append(newline);
+ if(stompBody != null){
+ stringBuilder.append(stompBody).append(newline);
+ }
+ stringBuilder.append(terminator);
+ return stringBuilder.toString();
+ }
+
+ public Map getStompHeaders() {
+ return stompHeaders;
+ }
+
+ public StompCommandName getStompCommand() {
+ return stompCommand;
+ }
+
+ public String getStompBody() {
+ return stompBody;
+ }
+}
diff --git a/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/payload/StompParser.java b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/payload/StompParser.java
new file mode 100644
index 0000000..99a5cf7
--- /dev/null
+++ b/droidstomplib/src/main/java/com/github/dadekuma/droidstomplib/payload/StompParser.java
@@ -0,0 +1,60 @@
+package com.github.dadekuma.droidstomplib.payload;
+
+import android.util.Log;
+
+import com.github.dadekuma.droidstomplib.enums.StompCommandName;
+import com.github.dadekuma.droidstomplib.enums.StompHeaderName;
+import com.github.dadekuma.droidstomplib.enums.StompSymbolName;
+
+public class StompParser {
+ public static StompFrame parse(String message) {
+ StompFrame stompFrame = new StompFrame();
+ String[] messageRows = message.split(StompSymbolName.NEWLINE.toString());
+ try {
+ StompCommandName stompCommandName = StompCommandName.getEnum(messageRows[0]);
+ stompFrame.addStompCommand(stompCommandName);
+ }
+ catch (IllegalArgumentException e){
+ Log.e("STOMP_ILLEGAL_COMMAND", e.getMessage());
+ }
+ catch (RuntimeException e){
+ e.fillInStackTrace();
+ Log.e("STOMP_PARSER_EX", e.getMessage());
+ }
+
+ int bodyPosition = 1;
+ for (int i = 1; i < messageRows.length; ++i) {
+ if (messageRows[i].equals("")) {
+ bodyPosition = i;
+ break;
+ }
+ try {
+ String[] header = messageRows[i].split(StompSymbolName.SEPARATOR.toString());
+ StompHeaderName headerName = StompHeaderName.getEnum(header[0]);
+ String headerValue = header[1];
+ stompFrame.addStompHeader(headerName, headerValue);
+ }
+ catch (IllegalArgumentException e){
+ Log.e("STOMP_ILLEGAL_HEADER", e.getMessage());
+ }
+ catch (RuntimeException e){
+ e.fillInStackTrace();
+ Log.e("STOMP_PARSER_EX", e.getMessage());
+ }
+ }
+ String stompBody = parseBody(bodyPosition, messageRows);
+ stompFrame.addBody(stompBody);
+ return stompFrame;
+ }
+
+ private static String parseBody(int startPosition, String[] messageRows){
+ StringBuilder stompBody = new StringBuilder();
+ for (int i = startPosition; i < messageRows.length; i++) {
+ if(messageRows[i].equals(StompSymbolName.TERMINATOR.toString())){
+ break;
+ }
+ stompBody.append(messageRows[i]);
+ }
+ return stompBody.toString();
+ }
+}
\ No newline at end of file
diff --git a/droidstomplib/src/main/res/values/strings.xml b/droidstomplib/src/main/res/values/strings.xml
new file mode 100644
index 0000000..6d6df04
--- /dev/null
+++ b/droidstomplib/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ DroidSTOMP
+
diff --git a/droidstomplib/src/test/java/com/github/dadekuma/droidstomplib/ExampleUnitTest.java b/droidstomplib/src/test/java/com/github/dadekuma/droidstomplib/ExampleUnitTest.java
new file mode 100644
index 0000000..376b64f
--- /dev/null
+++ b/droidstomplib/src/test/java/com/github/dadekuma/droidstomplib/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.github.dadekuma.droidstomplib;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/droidstomplib/src/test/java/com/github/dadekuma/droidstomplib/StompFrameTest.java b/droidstomplib/src/test/java/com/github/dadekuma/droidstomplib/StompFrameTest.java
new file mode 100644
index 0000000..368a9f9
--- /dev/null
+++ b/droidstomplib/src/test/java/com/github/dadekuma/droidstomplib/StompFrameTest.java
@@ -0,0 +1,66 @@
+package com.github.dadekuma.droidstomplib;
+
+import com.github.dadekuma.droidstomplib.enums.StompCommandName;
+import com.github.dadekuma.droidstomplib.enums.StompHeaderName;
+import com.github.dadekuma.droidstomplib.payload.StompFrame;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class StompFrameTest {
+ private StompFrame stompFrame;
+
+ @Before
+ public void initStompFrame(){
+ stompFrame = new StompFrame();
+ }
+
+ @Test
+ public void buildTest(){
+ stompFrame.addStompCommand(StompCommandName.CONNECT);
+ stompFrame.addStompHeader(StompHeaderName.ID, "1");
+ String result = stompFrame.build();
+ String expected = "CONNECT\n" +
+ "id:1\n" +
+ "\n" +
+ "\u0000";
+ Assert.assertEquals(expected, result);
+ }
+
+ @Test
+ public void buildMultipleHeadersTest(){
+ stompFrame.addStompCommand(StompCommandName.SEND);
+ stompFrame.addStompHeader(StompHeaderName.ID, "10")
+ .addStompHeader(StompHeaderName.DESTINATION, "/topic/example")
+ .addStompHeader(StompHeaderName.CONTENT_TYPE, "text-plain");
+ String result = stompFrame.build();
+ String expected = "SEND\n" +
+ "id:10\n" +
+ "destination:/topic/example\n" +
+ "content-type:text-plain\n" +
+ "\n" +
+ "\u0000";
+ Assert.assertEquals(expected, result);
+ }
+
+ @Test
+ public void buildWithBody(){
+ stompFrame.addStompCommand(StompCommandName.MESSAGE);
+ stompFrame.addStompHeader(StompHeaderName.SUBSCRIPTION, "10")
+ .addStompHeader(StompHeaderName.MESSAGE_ID,"004")
+ .addStompHeader(StompHeaderName.DESTINATION, "/topic/example")
+ .addStompHeader(StompHeaderName.CONTENT_TYPE, "text-plain")
+ .addBody("Hello darkness my old friend");
+ String result = stompFrame.build();
+ String expected = "MESSAGE\n" +
+ "subscription:10\n" +
+ "message-id:004\n" +
+ "destination:/topic/example\n" +
+ "content-type:text-plain\n" +
+ "\n" +
+ "Hello darkness my old friend\n" +
+ "\u0000";
+ Assert.assertEquals(expected, result);
+ }
+}
\ No newline at end of file