From 876f07840f6fa73e6f2ca0350d4ca8922c869075 Mon Sep 17 00:00:00 2001
From: Vitaly Takmazov
Date: Wed, 14 Mar 2018 09:12:53 +0300
Subject: reorganize project structure
---
.../com/juick/server/protocol/JuickProtocol.java | 188 +++++++++++++++++++++
.../juick/server/protocol/ProtocolListener.java | 30 ++++
.../server/protocol/annotation/UserCommand.java | 50 ++++++
.../xmpp/core/session/debug/LogbackDebugger.java | 57 +++++++
4 files changed, 325 insertions(+)
create mode 100644 juick-server-web/src/main/java/com/juick/server/protocol/JuickProtocol.java
create mode 100644 juick-server-web/src/main/java/com/juick/server/protocol/ProtocolListener.java
create mode 100644 juick-server-web/src/main/java/com/juick/server/protocol/annotation/UserCommand.java
create mode 100644 juick-server-web/src/main/java/rocks/xmpp/core/session/debug/LogbackDebugger.java
(limited to 'juick-server-web/src/main')
diff --git a/juick-server-web/src/main/java/com/juick/server/protocol/JuickProtocol.java b/juick-server-web/src/main/java/com/juick/server/protocol/JuickProtocol.java
new file mode 100644
index 00000000..1be34a3f
--- /dev/null
+++ b/juick-server-web/src/main/java/com/juick/server/protocol/JuickProtocol.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2008-2017, Juick
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.juick.server.protocol;
+
+import com.juick.Message;
+import com.juick.Tag;
+import com.juick.User;
+import com.juick.formatters.PlainTextFormatter;
+import com.juick.server.protocol.annotation.UserCommand;
+import com.juick.server.util.TagUtils;
+import com.juick.service.*;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.commons.lang3.reflect.MethodUtils;
+
+import javax.inject.Inject;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * Created by oxpa on 22.03.16.
+ */
+
+public class JuickProtocol {
+
+ private String baseUri;
+ private ProtocolListener listener;
+
+ @Inject
+ UserService userService;
+ @Inject
+ TagService tagService;
+ @Inject
+ MessagesService messagesService;
+ @Inject
+ SubscriptionService subscriptionService;
+ @Inject
+ PMQueriesService pmQueriesService;
+ @Inject
+ PrivacyQueriesService privacyQueriesService;
+ @Inject
+ ShowQueriesService showQueriesService;
+
+ public JuickProtocol(String baseUri) {
+ this.baseUri = baseUri;
+ }
+
+ /**
+ * find command by pattern and invoke
+ * @param user who send command
+ * @param userInput given by user
+ * @return command result
+ * @throws InvocationTargetException
+ * @throws IllegalAccessException
+ * @throws NoSuchMethodException
+ */
+ public String getReply(User user, String userInput) throws InvocationTargetException,
+ IllegalAccessException, NoSuchMethodException {
+ Optional cmd = MethodUtils.getMethodsListWithAnnotation(getClass(), UserCommand.class).stream()
+ .filter(m -> Pattern.compile(m.getAnnotation(UserCommand.class).pattern(),
+ m.getAnnotation(UserCommand.class).patternFlags()).matcher(userInput).matches())
+ .findFirst();
+ if (!cmd.isPresent()) {
+ // default command - post as new message
+ return postMessage(user, userInput.trim());
+ } else {
+ Matcher matcher = Pattern.compile(cmd.get().getAnnotation(UserCommand.class).pattern(),
+ cmd.get().getAnnotation(UserCommand.class).patternFlags()).matcher(userInput.trim());
+ List groups = new ArrayList<>();
+ while (matcher.find()) {
+ for (int i = 1; i <= matcher.groupCount(); i++) {
+ groups.add(matcher.group(i));
+ }
+ }
+ return (String) getClass().getMethod(cmd.get().getName(), User.class, String[].class)
+ .invoke(this, user, groups.toArray(new String[groups.size()]));
+ }
+ }
+
+ public String postMessage(User user, String input) {
+ List tags = tagService.fromString(input, false);
+ String body = input.substring(TagUtils.toString(tags).length());
+ int mid = messagesService.createMessage(user.getUid(), body, null, tags);
+ subscriptionService.subscribeMessage(mid, user.getUid());
+ listener.messagePosted(messagesService.getMessage(mid));
+ return "New message posted.\n#" + mid + " " + baseUri + mid;
+ }
+
+
+
+
+ @UserCommand(pattern = "^d\\s*\\#([0-9]+)$", patternFlags = Pattern.CASE_INSENSITIVE,
+ help = "D #12345 - delete the message")
+ public String commandDel(User user, String... args) {
+ int mid = NumberUtils.toInt(args[0], 0);
+ if (messagesService.deleteMessage(user.getUid(), mid)) {
+ return String.format("Message %s deleted", mid);
+ }
+ return "Error";
+ }
+
+
+ @UserCommand(pattern = "^(#+)$", help = "# - Show last messages from your feed (## - second page, ...)")
+ public String commandMyFeed(User user, String... arguments) {
+ // number of # is the page count
+ int page = arguments[0].length() - 1;
+ List mids = messagesService.getMyFeed(user.getUid(), page, false);
+ List messages = messagesService.getMessages(mids);
+ // TODO: add instructions for empty feed
+ return "Your feed: \n" + String.join("\n",
+ messages.stream().map(PlainTextFormatter::formatPost).collect(Collectors.toList()));
+ }
+ @UserCommand(pattern = "^(#|\\.)(\\d+)((\\.|\\-|\\/)(\\d+))?\\s([\\s\\S]+)",
+ help = "#1234 *tag *tag2 - edit tags\n#1234 text - reply to message")
+ public String EditOrReply(User user, String... args) {
+ int mid = NumberUtils.toInt(args[1]);
+ int rid = NumberUtils.toInt(args[4], 0);
+ String txt = args[5];
+ List messageTags = tagService.fromString(txt, true);
+ if (messageTags.size() > 0) {
+ if (user.getUid() != messagesService.getMessageAuthor(mid).getUid()) {
+ return "It is not your message";
+ }
+ tagService.updateTags(mid, messageTags);
+ return "Tags are updated";
+ } else {
+ int newrid = messagesService.createReply(mid, rid, user.getUid(), txt, null);
+ listener.messagePosted(messagesService.getReply(mid, newrid));
+ return "Reply posted.\n#" + mid + "/" + newrid + " "
+ + baseUri + mid + "#" + newrid;
+ }
+ }
+
+
+ @UserCommand(pattern = "^(s|u)\\s+\\@(\\S+)$", help = "S @user - subscribe to user's posts",
+ patternFlags = Pattern.CASE_INSENSITIVE)
+ public String commandSubscribeUser(User user, String... args) {
+ boolean subscribe = args[0].equalsIgnoreCase("s");
+ User toUser = userService.getUserByName(args[1]);
+ if (toUser.getUid() > 0) {
+ if (subscribe) {
+ if (subscriptionService.subscribeUser(user, toUser)) {
+ listener.userSubscribed(user, toUser);
+ return "Subscribed";
+ // TODO: already subscribed case
+ }
+ } else {
+ if (subscriptionService.unSubscribeUser(user, toUser)) {
+ return "Unsubscribed from @" + toUser.getName();
+ }
+ return "You was not subscribed to @" + toUser.getName();
+ }
+ }
+ return "Error";
+ }
+
+ public String getBaseUri() {
+ return baseUri;
+ }
+
+ public ProtocolListener getListener() {
+ return listener;
+ }
+
+ public void setListener(ProtocolListener listener) {
+ this.listener = listener;
+ }
+}
diff --git a/juick-server-web/src/main/java/com/juick/server/protocol/ProtocolListener.java b/juick-server-web/src/main/java/com/juick/server/protocol/ProtocolListener.java
new file mode 100644
index 00000000..f051e6d0
--- /dev/null
+++ b/juick-server-web/src/main/java/com/juick/server/protocol/ProtocolListener.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2008-2017, Juick
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.juick.server.protocol;
+
+import com.juick.Message;
+import com.juick.User;
+
+/**
+ * Created by vitalyster on 19.12.2016.
+ */
+public interface ProtocolListener {
+ void privateMessage(User from, User to, String body);
+ void userSubscribed(User from, User to);
+ void messagePosted(Message msg);
+}
diff --git a/juick-server-web/src/main/java/com/juick/server/protocol/annotation/UserCommand.java b/juick-server-web/src/main/java/com/juick/server/protocol/annotation/UserCommand.java
new file mode 100644
index 00000000..ab37a4e1
--- /dev/null
+++ b/juick-server-web/src/main/java/com/juick/server/protocol/annotation/UserCommand.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008-2017, Juick
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.juick.server.protocol.annotation;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by oxpa on 22.03.16.
+ */
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface UserCommand {
+ /**
+ *
+ * @return a command pattern
+ */
+ String pattern() default StringUtils.EMPTY;
+
+ /**
+ *
+ * @return pattern flags
+ */
+ int patternFlags() default 0;
+
+ /**
+ *
+ * @return a string used in HELP command output. Basically, only 1 string
+ */
+ String help() default StringUtils.EMPTY;
+}
diff --git a/juick-server-web/src/main/java/rocks/xmpp/core/session/debug/LogbackDebugger.java b/juick-server-web/src/main/java/rocks/xmpp/core/session/debug/LogbackDebugger.java
new file mode 100644
index 00000000..bbf35996
--- /dev/null
+++ b/juick-server-web/src/main/java/rocks/xmpp/core/session/debug/LogbackDebugger.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008-2017, Juick
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package rocks.xmpp.core.session.debug;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import rocks.xmpp.core.session.XmppSession;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Created by vitalyster on 17.11.2016.
+ */
+public class LogbackDebugger implements XmppDebugger {
+ private Logger logger;
+
+ @Override
+ public void initialize(XmppSession xmppSession) {
+ logger = LoggerFactory.getLogger(xmppSession.getClass());
+ }
+
+ @Override
+ public void writeStanza(String s, Object o) {
+ logger.debug("OUT: {}", s);
+ }
+
+ @Override
+ public void readStanza(String s, Object o) {
+ logger.debug("IN: {}", s);
+ }
+
+ @Override
+ public OutputStream createOutputStream(OutputStream outputStream) {
+ return outputStream;
+ }
+
+ @Override
+ public InputStream createInputStream(InputStream inputStream) {
+ return inputStream;
+ }
+}
--
cgit v1.2.3