From 75cb488222629a36d20765f5dada5fea1c83b6cf Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Mon, 19 Dec 2016 15:36:13 +0300 Subject: juick-server: JuickProtocol refactoring --- .../com/juick/server/protocol/JuickProtocol.java | 109 ++++++--------------- .../juick/server/protocol/ProtocolListener.java | 11 +++ .../main/java/com/juick/components/XMPPBot.java | 48 ++++++++- 3 files changed, 87 insertions(+), 81 deletions(-) create mode 100644 juick-server/src/main/java/com/juick/server/protocol/ProtocolListener.java diff --git a/juick-server/src/main/java/com/juick/server/protocol/JuickProtocol.java b/juick-server/src/main/java/com/juick/server/protocol/JuickProtocol.java index 6f61e4d6..a024a0eb 100644 --- a/juick-server/src/main/java/com/juick/server/protocol/JuickProtocol.java +++ b/juick-server/src/main/java/com/juick/server/protocol/JuickProtocol.java @@ -1,8 +1,5 @@ package com.juick.server.protocol; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import com.juick.Message; import com.juick.Tag; import com.juick.User; @@ -16,7 +13,10 @@ import org.apache.commons.lang3.math.NumberUtils; import javax.inject.Inject; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -26,8 +26,10 @@ import java.util.stream.Collectors; */ public class JuickProtocol { - private final ObjectMapper json; + private String baseUri; + private ProtocolListener listener; + @Inject UserService userService; @Inject @@ -45,10 +47,6 @@ public class JuickProtocol { public JuickProtocol(String baseUri) { this.baseUri = baseUri; - json = new ObjectMapper(); - json.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); - json.setSerializationInclusion(JsonInclude.Include.NON_NULL); - json.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT); } /** @@ -61,7 +59,7 @@ public class JuickProtocol { * @throws NoSuchMethodException */ public ProtocolReply getReply(User user, String userInput) throws InvocationTargetException, - IllegalAccessException, NoSuchMethodException, JsonProcessingException { + IllegalAccessException, NoSuchMethodException { Optional cmd = Arrays.stream(getClass().getDeclaredMethods()) .filter(m -> m.isAnnotationPresent(UserCommand.class)) .filter(m -> Pattern.compile(m.getAnnotation(UserCommand.class).pattern(), @@ -84,7 +82,7 @@ public class JuickProtocol { } } - public ProtocolReply postMessage(User user, String input) throws JsonProcessingException { + public ProtocolReply 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); @@ -93,7 +91,7 @@ public class JuickProtocol { } @UserCommand(pattern = "^#(\\++)$", help = "#+ - Show last Juick messages (#++ - second page, ...)") - public ProtocolReply commandLast(User user, String... arguments) throws JsonProcessingException { + public ProtocolReply commandLast(User user, String... arguments) { // number of + is the page count int page = arguments[0].length() - 1; List mids = messagesService.getAll(user.getUid(), page); @@ -200,7 +198,7 @@ public class JuickProtocol { } @UserCommand(pattern = "!", help = "! - Show your favorite messages") - public ProtocolReply commandFavorites(User currentUser, String... args) throws JsonProcessingException { + public ProtocolReply commandFavorites(User currentUser, String... args) { List mids = messagesService.getUserRecommendations(currentUser.getUid(), 0); if (mids.size() > 0) { List messages = messagesService.getMessages(mids); @@ -212,7 +210,7 @@ public class JuickProtocol { @UserCommand(pattern = "^\\@([^\\s\\n\\+]+)(\\+?)$", help = "@username+ - Show user's info and last 10 messages (@username++ - second page, ..)") - public ProtocolReply commandUser(User user, String... arguments) throws JsonProcessingException { + public ProtocolReply commandUser(User user, String... arguments) { User blogUser = userService.getUserByName(arguments[0]); int page = arguments[1].length(); if (blogUser != null) { @@ -242,7 +240,7 @@ public class JuickProtocol { } @UserCommand(pattern = "^(#+)$", help = "# - Show last messages from your feed (## - second page, ...)") - public ProtocolReply commandMyFeed(User user, String... arguments) throws JsonProcessingException { + public ProtocolReply commandMyFeed(User user, String... arguments) { // number of # is the page count int page = arguments[0].length() - 1; List mids = messagesService.getMyFeed(user.getUid(), page); @@ -282,68 +280,22 @@ public class JuickProtocol { public ProtocolReply commandPM(User user_from, String... arguments) { String user_to = arguments[0]; String body = arguments[1]; - int ret = 0; - - int uid_to = 0; - String jid_to = null; - boolean haveInRoster = false; - - if (user_to.indexOf('@') > 0) { - uid_to = userService.getUIDbyJID(user_to); - } else { - uid_to = userService.getUIDbyName(user_to); - } - - if (uid_to > 0) { - if (!userService.isInBLAny(uid_to, user_from.getUid())) { - if (pmQueriesService.createPM(user_from.getUid(), uid_to, body)) { - //jid_to = UserQueries.getJIDsbyUID(sql, uid_to); - if (jid_to != null) { - haveInRoster = pmQueriesService.havePMinRoster(user_from.getUid(), jid_to); - } - ret = 200; - } else { - ret = 500; - } - } else { - ret = 403; - } - } else { - ret = 404; - } + User toUser = userService.getUserByName(user_to); - if (ret == 200) { - Message jmsg = new Message(); - jmsg.setUser(user_from); - jmsg.setText(body); - // TODO: add PM payload - //app.events().publishEvent(new JuickMessageEvent(jmsg)); - /* TODO: move to XMPP component - if (jid_to != null) { - Message mm = new Message(); - mm.to = new JID(jid_to); - mm.type = Message.Type.chat; - if (haveInRoster) { - mm.from = new JID(user_from.getName(), getDomain(), "Juick"); - mm.body = body; - } else { - mm.from = new JID("juick", getDomain(), "Juick"); - mm.body = "Private message from @" + user_from.getName() + ":\n" + body; + if (toUser.getUid() > 0) { + if (!userService.isInBLAny(toUser.getUid(), user_from.getUid())) { + if (pmQueriesService.createPM(user_from.getUid(), toUser.getUid(), body)) { + listener.privateMessage(user_from, toUser, body); + return new ProtocolReply("Private message sent"); } - return Collections.singletonList(mm); } - */ - } - if (ret == 200) { - return new ProtocolReply("Private message sent"); - } else { - return new ProtocolReply("Error " + ret); } + return new ProtocolReply("Error"); } @UserCommand(pattern = "^#(\\d+)(\\+?)$", help = "#1234 - Show message (#1234+ - message with replies)") - public ProtocolReply commandShow(User user, String... arguments) throws JsonProcessingException { + public ProtocolReply commandShow(User user, String... arguments) { boolean showReplies = arguments[1].length() > 0; int mid; try { @@ -365,13 +317,8 @@ public class JuickProtocol { } @UserCommand(pattern = "^(#|\\.)(\\d+)((\\.|\\-|\\/)(\\d+))?\\s([\\s\\S]+)", help = "#1234 *tag *tag2 - edit tags\n#1234 text - reply to message") - public ProtocolReply EditOrReply(User user, String... args) throws JsonProcessingException { - int mid; - try { - mid = Integer.parseInt(args[1]); - } catch (NumberFormatException e) { - return new ProtocolReply("Error"); - } + public ProtocolReply 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); @@ -413,8 +360,8 @@ public class JuickProtocol { if (toUser.getUid() > 0) { if (subscribe) { if (subscriptionService.subscribeUser(user, toUser)) { + listener.userSubscribed(user, toUser); return new ProtocolReply("Subscribed"); - // TODO: notification // TODO: already subscribed case } } else { @@ -457,4 +404,12 @@ public class JuickProtocol { public String getBaseUri() { return baseUri; } + + public ProtocolListener getListener() { + return listener; + } + + public void setListener(ProtocolListener listener) { + this.listener = listener; + } } diff --git a/juick-server/src/main/java/com/juick/server/protocol/ProtocolListener.java b/juick-server/src/main/java/com/juick/server/protocol/ProtocolListener.java new file mode 100644 index 00000000..719520c7 --- /dev/null +++ b/juick-server/src/main/java/com/juick/server/protocol/ProtocolListener.java @@ -0,0 +1,11 @@ +package com.juick.server.protocol; + +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); +} diff --git a/juick-xmpp-bot/src/main/java/com/juick/components/XMPPBot.java b/juick-xmpp-bot/src/main/java/com/juick/components/XMPPBot.java index 9f5d076a..234d04f8 100644 --- a/juick-xmpp-bot/src/main/java/com/juick/components/XMPPBot.java +++ b/juick-xmpp-bot/src/main/java/com/juick/components/XMPPBot.java @@ -1,10 +1,11 @@ package com.juick.components; -import com.fasterxml.jackson.core.JsonProcessingException; import com.juick.User; import com.juick.server.helpers.UserInfo; import com.juick.server.protocol.JuickProtocol; +import com.juick.server.protocol.ProtocolListener; import com.juick.server.protocol.ProtocolReply; +import com.juick.service.PMQueriesService; import com.juick.service.UserService; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.math.NumberUtils; @@ -24,24 +25,30 @@ import javax.inject.Inject; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.net.URL; +import java.util.List; /** * Created by vt on 12/11/2016. */ -public class XMPPBot implements AutoCloseable { +public class XMPPBot implements AutoCloseable, ProtocolListener { private static final Logger logger = LoggerFactory.getLogger(XMPPBot.class); @Inject UserService userService; @Inject + PMQueriesService pmQueriesService; + @Inject JuickProtocol juickProtocol; + Jid juickJid; + private ExternalComponent component; public XMPPBot(Environment env) { component = ExternalComponent.create(env.getProperty("component_name", "juick.com"), env.getProperty("component_password", "secret"), env.getProperty("component_host", "localhost"), NumberUtils.toInt(env.getProperty("component_port", "5347"), 5347)); - Jid juickJid = Jid.of(env.getProperty("xmppbot_jid", "juick@juick.com/Juick")); + juickJid = Jid.of(env.getProperty("xmppbot_jid", "juick@juick.com/Juick")); + juickProtocol.setListener(this); try { SoftwareVersionManager softwareVersionManager = component.getManager(SoftwareVersionManager.class); softwareVersionManager.setSoftwareVersion(new SoftwareVersion("Juick", "git", System.getProperty("os.name", "generic"))); @@ -79,7 +86,7 @@ public class XMPPBot implements AutoCloseable { replyMessage.setBody(reply.getResult()); replyMessage.setFrom(juickJid); component.send(replyMessage); - } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException | JsonProcessingException ex) { + } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException ex) { logger.warn("unhandled error", ex); } } @@ -97,4 +104,37 @@ public class XMPPBot implements AutoCloseable { logger.info("ExternalComponent on xmpp-bot destroyed"); } + + @Override + public void privateMessage(User from, User to, String body) { + List toJids = userService.getJIDsbyUID(to.getUid()); + toJids.forEach(jid -> { + Message mm = new Message(); + mm.setTo(Jid.of(jid)); + mm.setType(Message.Type.CHAT); + boolean haveInRoster = pmQueriesService.havePMinRoster(from.getUid(), jid); + if (haveInRoster) { + mm.setFrom(Jid.of(from.getName(), juickJid.getDomain(), "Juick")); + mm.setBody(body); + } else { + mm.setFrom(Jid.of("juick", juickJid.getDomain(), "Juick")); + mm.setBody("Private message from @" + from.getName() + ":\n" + body); + } + component.send(mm); + }); + } + + @Override + public void userSubscribed(User from, User to) { + String notification = String.format("%s subscribed to your blog", from.getName()); + List toJids = userService.getJIDsbyUID(to.getUid()); + toJids.forEach(jid -> { + Message mm = new Message(); + mm.setTo(Jid.of(jid)); + mm.setType(Message.Type.CHAT); + mm.setFrom(juickJid); + mm.setBody(notification); + component.send(mm); + }); + } } -- cgit v1.2.3