From aabad2347aaf52e225541cb954e98ab509e9aa2f Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Fri, 1 Mar 2019 19:17:40 +0300 Subject: Tags refactoring --- src/main/java/com/juick/Message.java | 15 +++++----- .../com/juick/service/MessagesServiceImpl.java | 2 +- src/main/java/com/juick/util/MessageUtils.java | 30 ++++++++++---------- .../pebble/extension/filters/TagsListFilter.java | 5 ++-- .../java/com/juick/server/tests/ServerTests.java | 32 ++++++++++++---------- 5 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/juick/Message.java b/src/main/java/com/juick/Message.java index 617ed834..fb6be67c 100644 --- a/src/main/java/com/juick/Message.java +++ b/src/main/java/com/juick/Message.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2017, Juick + * Copyright (C) 2008-2019, 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 @@ -24,12 +24,13 @@ import com.juick.model.Entity; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.builder.ToStringBuilder; +import javax.annotation.Nonnull; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import java.net.URI; import java.time.Instant; -import java.util.ArrayList; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; import java.util.Set; @@ -45,7 +46,7 @@ public class Message implements Comparable { private int replyto = 0; private String text = null; private User user = null; - private final List tags; + private final Set tags; private Instant ts; private Instant updated; private Instant updatedAt; @@ -86,7 +87,7 @@ public class Message implements Comparable { private List entities; public Message() { - tags = new ArrayList<>(); + tags = new LinkedHashSet<>(); reactions = new HashSet<>(); } @@ -120,7 +121,7 @@ public class Message implements Comparable { } @Override - public int compareTo(Object obj) throws ClassCastException { + public int compareTo(@Nonnull Object obj) throws ClassCastException { if (obj == this) return 0; @@ -218,11 +219,11 @@ public class Message implements Comparable { @JsonProperty("tags") @XmlElement(name = "tag") - public List getTags() { + public Set getTags() { return tags; } - public void setTags(List tags) { + public void setTags(Set tags) { this.tags.clear(); if (CollectionUtils.isNotEmpty(tags)) this.tags.addAll(tags); diff --git a/src/main/java/com/juick/service/MessagesServiceImpl.java b/src/main/java/com/juick/service/MessagesServiceImpl.java index 2a107fbf..e95742ab 100644 --- a/src/main/java/com/juick/service/MessagesServiceImpl.java +++ b/src/main/java/com/juick/service/MessagesServiceImpl.java @@ -98,7 +98,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ msg.setAttachmentType(rs.getString(11)); msg.setLikes(rs.getInt(12)); msg.Hidden = rs.getBoolean(13); - String tagsStr = rs.getString(14); + String tagsStr = StringUtils.defaultString(rs.getString(14)); msg.setTags(MessageUtils.parseTags(tagsStr)); msg.setRepliesBy(rs.getString(15)); msg.setText(rs.getString(16)); diff --git a/src/main/java/com/juick/util/MessageUtils.java b/src/main/java/com/juick/util/MessageUtils.java index 78899ca2..fa94e978 100644 --- a/src/main/java/com/juick/util/MessageUtils.java +++ b/src/main/java/com/juick/util/MessageUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2017, Juick + * Copyright (C) 2008-2019, 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 @@ -28,7 +28,13 @@ import org.springframework.web.util.UriComponentsBuilder; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLEncoder; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -299,23 +305,15 @@ public class MessageUtils { public static boolean replyStartsWithQuote(Message msg) { return msg.getRid() > 0 && StringUtils.defaultString(msg.getText()).startsWith(">"); } - public static List parseTags(String strTags) { - List tags = new ArrayList<>(); - if (StringUtils.isNotEmpty(strTags)) { - Set tagSet = new TreeSet<>(tags); - for (String str : strTags.split(" ")) { - Tag tag = new Tag(str); - if (!tagSet.contains(tag)) { - tags.add(tag); - tagSet.add(tag); - } - } - } - return tags; + public static Set parseTags(String strTags) { + return StringUtils.isEmpty(strTags) ? Collections.emptySet() + : Arrays.stream(strTags.split(" ")).map(Tag::new) + .collect(Collectors.toCollection(LinkedHashSet::new)); } public static String getTagsString(Message msg) { StringBuilder builder = new StringBuilder(); - List tags = msg.getTags(); + Set tags = msg.getTags(); + if (!tags.isEmpty()) { for (Tag Tag : tags) builder.append(" *").append(Tag.getName()); diff --git a/src/main/java/com/mitchellbosecke/pebble/extension/filters/TagsListFilter.java b/src/main/java/com/mitchellbosecke/pebble/extension/filters/TagsListFilter.java index c7b00ea3..c83c3a45 100644 --- a/src/main/java/com/mitchellbosecke/pebble/extension/filters/TagsListFilter.java +++ b/src/main/java/com/mitchellbosecke/pebble/extension/filters/TagsListFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2017, Juick + * Copyright (C) 2008-2019, 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 @@ -22,6 +22,7 @@ import com.mitchellbosecke.pebble.extension.Filter; import com.mitchellbosecke.pebble.template.EvaluationContext; import com.mitchellbosecke.pebble.template.PebbleTemplate; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -33,7 +34,7 @@ public class TagsListFilter implements Filter { @SuppressWarnings("unchecked") @Override public Object apply(Object input, Map args, PebbleTemplate self, EvaluationContext context, int lineNumber) { - return ((List) input).stream().map(Tag::getName).collect(Collectors.toList()); + return ((Collection) input).stream().map(Tag::getName).collect(Collectors.toList()); } @Override diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java index 3eb349e1..ad375e99 100644 --- a/src/test/java/com/juick/server/tests/ServerTests.java +++ b/src/test/java/com/juick/server/tests/ServerTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2017, Juick + * Copyright (C) 2008-2019, 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 @@ -361,7 +361,7 @@ public class ServerTests { Message msg3 = messagesService.getMessage(mid2).get(); assertEquals(2, msg3.getReplies()); - assertEquals("weather", msg3.getTags().get(0).getName()); + assertEquals("weather", msg3.getTags().stream().findFirst().get().getName()); assertEquals(ugnich.getUid(), userService.checkPassword(ugnich.getName(), "x")); assertEquals(-1, userService.checkPassword(ugnich.getName(), "xy")); @@ -722,7 +722,7 @@ public class ServerTests { tagService.getMessageTags(msg.getMid()).get(0).getTag().getName()); CommandResult yoyoMsg = commandsManager.processCommand(user, "*yo", URI.create("https://static.juick.com/settings/facebook.png")); assertTrue(yoyoMsg.getNewMessage().isPresent()); - assertThat(yoyoMsg.getNewMessage().get().getTags().get(0), is(yo)); + assertThat(yoyoMsg.getNewMessage().get().getTags().stream().findFirst().get(), is(yo)); Message msg2 = yoyoMsg.getNewMessage().get(); int mid = msg2.getMid(); Timestamp last = jdbcTemplate.queryForObject("SELECT lastmessage FROM users WHERE id=?", Timestamp.class, user.getUid()); @@ -826,11 +826,11 @@ public class ServerTests { "> }"; String codeAndTags = "*code\n" + expectedCodeMessage; Message codeAndTagsMessage = commandsManager.processCommand(user, codeAndTags, emptyUri).getNewMessage().get(); - List codeAndTagsTags = codeAndTagsMessage.getTags(); + Set codeAndTagsTags = codeAndTagsMessage.getTags(); assertEquals("expected single tag", 1, codeAndTagsTags.size()); assertEquals("the single tag should be the 'code'", "code", - codeAndTagsTags.get(0).getName()); + codeAndTagsTags.stream().findFirst().get().getName()); assertEquals("and the message should be with a C-code and without tags", expectedCodeMessage, codeAndTagsMessage.getText()); CommandResult result = commandsManager.processCommand(user, "*one *two *three *four *five *six test", emptyUri); @@ -854,7 +854,7 @@ public class ServerTests { data = "* \u043c\u0443\u0441\u043e\u0440\\n\u0423 \u043c\u0435\u043d\u044f \u043a\u0430\u0436\u0434\u0443\u044e \u043d\u0435\u0434\u0435\u043b\u044e \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043f\u043e 4-5 \u0431\u0443\u0442\u044b\u043b\u043e\u043a 1,5\u043b \u041f\u0415\u0422. \u041c\u043d\u0435 \u0433\u0435\u043c\u043e\u0440\u043d\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u043e \u043a\u0438\u043b\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0438\u043b\u0438 \u043f\u043e 5\u043a\u0433 \u044d\u0442\u043e\u0433\u043e \u043c\u0443\u0441\u043e\u0440\u0430, \u0447\u0442\u043e\u0431\u044b \u0432\u0435\u0437\u0442\u0438 \u0435\u0433\u043e \u0435\u0449\u0435 \u043a\u0443\u0434\u0430-\u0442\u043e.\\n\u041d\u0435, \u043d\u0443 \u0435\u0441\u0442\u044c \u043b\u044e\u0434\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442 \u0432\u0442\u043e\u0440\u0441\u044b\u0440\u044c\u0435 \u043f\u043e \u043c\u0443\u0441\u043e\u0440\u043a\u0430\u043c, \u0441\u0432\u0430\u043b\u043a\u0430\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0434\u0435\u043d\u044c\u0433\u0438 \u043d\u0443\u0436\u043d\u044b. \u0418 \u0431\u044b\u0432\u0430\u044e\u0442 \u0441\u0442\u043e\u044f\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b-\u043a\u043b\u0435\u0442\u043a\u0438 \u0434\u043b\u044f \u043f\u043b\u0430\u0441\u0442\u0438\u043a\u0430, \u043d\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u0443\u0441\u043e\u0440 \u0432\u044b\u0432\u043e\u0437\u044f\u0442 \u043d\u0435 \u0447\u0430\u0441\u0442\u043e \u0438\u043b\u0438 \u043b\u044e\u0434\u0438 \u0432\u043d\u0435\u0437\u0430\u043f\u043d\u043e \u0432\u044b\u043a\u0438\u0434\u044b\u0432\u0430\u044e\u0442 \u043c\u043d\u043e\u0433\u043e \u043c\u0443\u0441\u043e\u0440\u0430, \u0442\u043e \u0432 \u0442\u043e\u0439 \u043a\u043b\u0435\u0442\u043a\u0435 \u0442\u043e\u0442 \u043c\u0443\u0441\u043e\u0440, \u0447\u0442\u043e \u043d\u0435 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043b\u0441\u044f \u0432 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u0445."; result = commandsManager.processCommand(user, String.format("%s %s", tags, data), emptyUri); assertThat(result.getNewMessage().get().getTags().size(), equalTo(2)); - assertThat(result.getNewMessage().get().getTags().get(0).getName(), equalTo("Киев")); + assertThat(result.getNewMessage().get().getTags().stream().findFirst().get().getName(), equalTo("Киев")); assertThat(result.getNewMessage().get().getText(), equalTo(data)); result = commandsManager.processCommand(user, "S @unknown-user", emptyUri); assertThat(result.getNewMessage(), is(Optional.empty())); @@ -1024,16 +1024,19 @@ public class ServerTests { Tag xmlTag = (Tag) unmarshaller.unmarshal(new StringReader(tag)); assertThat(xmlTag.getName(), equalTo("yo")); Message juickMessage = xmppMessage.getExtension(Message.class); - assertThat(juickMessage.getTags().get(0).getName(), equalTo("yo")); + List tags = new ArrayList<>(juickMessage.getTags()); + assertThat(tags.get(0).getName(), equalTo("yo")); } @Test public void messageParserSerializer() throws ParserConfigurationException, IOException, SAXException, JAXBException { + Set tags = MessageUtils.parseTags("test test" + (char) 0xA0 + "2 test3"); + List tagList = new ArrayList<>(tags); + assertEquals("First tag must be", "test", tagList.get(0).getName()); + assertEquals("Third tag must be", "test3", tagList.get(2).getName()); + assertEquals("Count of tags must be", 3, tagList.size()); Message msg = new Message(); - msg.setTags(MessageUtils.parseTags("test test" + (char) 0xA0 + "2 test3")); - assertEquals("First tag must be", "test", msg.getTags().get(0).getName()); - assertEquals("Third tag must be", "test3", msg.getTags().get(2).getName()); - assertEquals("Count of tags must be", 3, msg.getTags().size()); + msg.setTags(tags); Instant currentDate = Instant.now(); msg.setTimestamp(currentDate); String jsonMessage = jsonMapper.writeValueAsString(msg); @@ -1660,9 +1663,10 @@ public class ServerTests { CommandResult result = commandsManager.processCommand(ugnich, "*test1 *test2 *test1 test3", emptyUri); assertThat(result.getNewMessage().isPresent(), is(true)); Message msg = result.getNewMessage().get(); - assertThat(msg.getTags().size(), is (2)); - assertThat(msg.getTags().get(0).getName(), is("test1")); - assertThat(msg.getTags().get(1).getName(), is("test2")); + List tags = new ArrayList<>(msg.getTags()); + assertThat(tags.size(), is (2)); + assertThat(tags.get(0).getName(), is("test1")); + assertThat(tags.get(1).getName(), is("test2")); assertThat(msg.getText(), is("test3")); } @Test -- cgit v1.2.3