From 69a5bdba32cdf0a48e51baa8c9fb28dca013f515 Mon Sep 17 00:00:00 2001 From: Alexander Alexeev Date: Wed, 7 Dec 2016 18:56:43 +0700 Subject: message improvenments, checking for tag's duplicates --- juick-core/src/main/java/com/juick/Message.java | 150 +++++++++++-------- juick-core/src/main/java/com/juick/Tag.java | 14 +- .../src/test/java/com/juick/MessageTest.java | 166 +++++++++++++++++++++ .../main/java/com/juick/components/Crosspost.java | 5 +- .../java/com/juick/xmpp/extensions/JuickUser.java | 29 ++-- 5 files changed, 280 insertions(+), 84 deletions(-) create mode 100644 juick-core/src/test/java/com/juick/MessageTest.java diff --git a/juick-core/src/main/java/com/juick/Message.java b/juick-core/src/main/java/com/juick/Message.java index 702b74e5..ae13d7e9 100644 --- a/juick-core/src/main/java/com/juick/Message.java +++ b/juick-core/src/main/java/com/juick/Message.java @@ -21,7 +21,9 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.juick.xml.adapters.SimpleDateAdapter; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @@ -29,7 +31,6 @@ import java.util.*; import java.util.stream.Collectors; /** - * * @author Ugnich Anton */ @XmlRootElement(name = "juick", namespace = "http://juick.com/message") @@ -40,7 +41,7 @@ public class Message implements Comparable { private int replyto = 0; private String text = null; private User user = null; - private List Tags = new ArrayList<>(); + private final List tags; private Date date; @XmlTransient @JsonIgnore @@ -67,12 +68,14 @@ public class Message implements Comparable { public String Video = null; public Place Place = null; private int likes; - public List childs = new ArrayList<>(); + public final List childs; private PM PM; private Recommendation Recommendation; private String replyQuote; public Message() { + tags = new ArrayList<>(); + childs = new ArrayList<>(); } public Message(Message msg) { @@ -81,7 +84,7 @@ public class Message implements Comparable { replyto = msg.replyto; setText(msg.getText()); setUser(msg.getUser()); - Tags = msg.Tags; + tags = msg.tags; setDate(msg.getDate()); TimeAgo = msg.TimeAgo; privacy = msg.privacy; @@ -100,46 +103,65 @@ public class Message implements Comparable { } public void parseTags(String strTags) { - if (strTags != null) { - List tags = Arrays.asList(strTags.split(" ")); - Tags.addAll(tags.stream().map(Tag::new).collect(Collectors.toList())); + 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); + } + } } } + @Override + public String toString() { + return new ToStringBuilder(this) + .append("mid", mid) + .append("rid", rid) + .append("replyto", replyto) + .append("TimeAgo", TimeAgo) + .append("privacy", privacy) + .append("FriendsOnly", FriendsOnly) + .append("ReadOnly", ReadOnly) + .append("Hidden", Hidden) + .append("VisitorCanComment", VisitorCanComment) + .append("replies", replies) + .append("likes", likes) + .toString(); + } + @Override public boolean equals(Object obj) { - if (!(obj instanceof Message)) { + if (obj == this) + return true; + + if (!(obj instanceof Message)) return false; - } + Message jmsg = (Message) obj; return (this.getMid() == jmsg.getMid() && this.getRid() == jmsg.getRid()); } @Override public int compareTo(Object obj) throws ClassCastException { - if (!(obj instanceof Message)) { + if (obj == this) + return 0; + + if (!(obj instanceof Message)) throw new ClassCastException(); - } + Message jmsg = (Message) obj; - if (this.getMid() != jmsg.getMid()) { - if (this.getMid() > jmsg.getMid()) { - return -1; - } else { - return 1; - } - } + int cmp = Integer.compare(jmsg.getMid(), getMid()); - if (this.getRid() != jmsg.getRid()) { - if (this.getRid() < jmsg.getRid()) { - return -1; - } else { - return 1; - } - } + if (cmp == 0) + cmp = Integer.compare(getRid(), jmsg.getRid()); - return 0; + return cmp; } + @JsonIgnore public int getChildsCount() { int cnt = childs.size(); @@ -161,42 +183,43 @@ public class Message implements Comparable { @JsonIgnore public String getAttachmentURL() { if (attachmentType != null) { - String url = "http://i.juick.com/"; - url += attachmentType.equals("mp4") ? "video" : "photos-1024"; - url += "/" + getMid(); - if (getRid() > 0) { - url += "-" + getRid(); - } - url += "." + attachmentType; - return url; - } else { - return null; + StringBuilder builder = new StringBuilder(); + + builder.append("http://i.juick.com/"); + builder.append(attachmentType.equals("mp4") ? "video" : "photos-1024"); + builder.append("/").append(getMid()); + + if (getRid() > 0) + builder.append("-").append(getRid()); + + builder.append(".").append(attachmentType); + + return builder.toString(); } + return null; } + @JsonIgnore public String getTagsString() { - String ret = ""; - if (!Tags.isEmpty()) { - for (Tag Tag : Tags) { - ret += " *" + Tag.getName(); - } - if (FriendsOnly) { - ret += " *friends"; - } - if (privacy == -2) { - ret += " *private"; - } - if (privacy == -1) { - ret += " *friends"; - } - if (privacy == 2) { - ret += " *public"; - } - if (ReadOnly) { - ret += " *readonly"; - } + StringBuilder builder = new StringBuilder(); + if (!tags.isEmpty()) { + for (Tag Tag : tags) + builder.append(" *").append(Tag.getName()); + + if (FriendsOnly) + builder.append(" *friends"); + + if (privacy == -2) + builder.append(" *private"); + else if (privacy == -1) + builder.append(" *friends"); + else if (privacy == 2) + builder.append(" *public"); + + if (ReadOnly) + builder.append(" *readonly"); } - return ret; + return builder.toString(); } @JsonProperty("mid") @@ -239,7 +262,7 @@ public class Message implements Comparable { } @JsonProperty("timestamp") - @JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss", timezone="UTC") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "UTC") @XmlAttribute(name = "ts") @XmlJavaTypeAdapter(SimpleDateAdapter.class) public Date getDate() { @@ -247,7 +270,6 @@ public class Message implements Comparable { } public void setDate(Date date) { - this.date = date; } @@ -262,6 +284,7 @@ public class Message implements Comparable { public Recommendation getRecommendation() { return Recommendation; } + public void setRecommendation(Recommendation recommendation) { this.Recommendation = recommendation; } @@ -270,6 +293,7 @@ public class Message implements Comparable { public String getReplyQuote() { return replyQuote; } + public void setReplyQuote(String quote) { replyQuote = quote; } @@ -287,11 +311,13 @@ public class Message implements Comparable { @JsonProperty("tags") @XmlElement(name = "tag") public List getTags() { - return Tags; + return tags; } public void setTags(List tags) { - Tags = tags; + this.tags.clear(); + if (CollectionUtils.isNotEmpty(tags)) + this.tags.addAll(tags); } @XmlAttribute @@ -329,6 +355,7 @@ public class Message implements Comparable { public void setReplies(int replies) { this.replies = replies; } + @XmlTransient public int getLikes() { return likes; @@ -346,6 +373,7 @@ public class Message implements Comparable { public void setRepliesBy(String repliesBy) { this.repliesBy = repliesBy; } + @JsonProperty("photo") @XmlTransient public Photo getPhotoURLs() { diff --git a/juick-core/src/main/java/com/juick/Tag.java b/juick-core/src/main/java/com/juick/Tag.java index 98fe60ff..9675390b 100644 --- a/juick-core/src/main/java/com/juick/Tag.java +++ b/juick-core/src/main/java/com/juick/Tag.java @@ -23,6 +23,7 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlValue; +import java.util.Comparator; import java.util.Objects; /** @@ -30,16 +31,12 @@ import java.util.Objects; */ @XmlRootElement(name = "tag", namespace = "http://juick.com/message") @XmlAccessorType(XmlAccessType.PROPERTY) -public class Tag { - private String name; +public class Tag implements Comparable { + private final String name; public int TID = 0; public int SynonymID = 0; - public Tag() { - - } - public Tag(String name) { this.name = name; } @@ -61,7 +58,8 @@ public class Tag { return name; } - public void setName(String name) { - this.name = name; + @Override + public int compareTo(Tag o) { + return Objects.compare(name, o.getName(), Comparator.naturalOrder()); } } diff --git a/juick-core/src/test/java/com/juick/MessageTest.java b/juick-core/src/test/java/com/juick/MessageTest.java new file mode 100644 index 00000000..a3d0a45b --- /dev/null +++ b/juick-core/src/test/java/com/juick/MessageTest.java @@ -0,0 +1,166 @@ +package com.juick; + +import org.apache.commons.lang3.RandomUtils; +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +/** + * Created by aalexeev on 12/7/16. + */ +public class MessageTest { + + @Test + public void equalsShouldBeReturnCorrectResult() throws Exception { + Message message1 = new Message(); + + Message message2 = new Message(); + message2.setMid(RandomUtils.nextInt()); + + Message message3 = message1; + + assertThat(message1, equalTo(message3)); + assertThat(message3, equalTo(message1)); + + assertThat(message1, not(equalTo(message2))); + assertThat(message2, not(equalTo(message1))); + + int id = RandomUtils.nextInt(); + message1.setMid(id); + message2.setMid(id); + + id = RandomUtils.nextInt(); + message1.setRid(id); + message2.setRid(id); + + assertThat(message1, equalTo(message2)); + assertThat(message2, equalTo(message1)); + + message1.setMid(RandomUtils.nextInt()); + message1.setRid(RandomUtils.nextInt()); + + message2.setMid(RandomUtils.nextInt()); + message2.setRid(RandomUtils.nextInt()); + + assertThat(message1, not(equalTo(message2))); + assertThat(message2, not(equalTo(message1))); + } + + @Test + public void compareShouldBeReturnCorrectResult() throws Exception { + Message message1 = new Message(); + + message1.setMid(RandomUtils.nextInt()); + message1.setRid(RandomUtils.nextInt()); + + Message message2 = message1; + + assertThat(message1.compareTo(message2), equalTo(0)); + assertThat(message2.compareTo(message1), equalTo(0)); + + Message message3 = new Message(); + + message3.setMid(message1.getMid()); + message3.setRid(message1.getRid()); + + assertThat(message1.compareTo(message3), equalTo(0)); + assertThat(message3.compareTo(message1), equalTo(0)); + } + + @Test + public void messageWithGreaterMidShouldBeLessThenMesageWithLessMid() throws Exception { + Message message1 = new Message(); + + message1.setMid(RandomUtils.nextInt()); + message1.setRid(RandomUtils.nextInt()); + + Message message2 = new Message(); + + message2.setMid(message1.getMid() + RandomUtils.nextInt(1, 10000)); + message2.setRid(RandomUtils.nextInt()); + + assertThat(message1.compareTo(message2), equalTo(1)); + assertThat(message2.compareTo(message1), equalTo(-1)); + } + + @Test + public void messageWithGreaterRidAndEqualsMidShouldBeGreaterThenMessageWithLessRid() throws Exception { + Message message1 = new Message(); + + message1.setMid(RandomUtils.nextInt()); + message1.setRid(RandomUtils.nextInt()); + + Message message2 = new Message(); + + message2.setMid(message1.getMid()); + message2.setRid(message1.getRid() + + RandomUtils.nextInt(1, 10000)); + + assertThat(message1.compareTo(message2), equalTo(-1)); + assertThat(message2.compareTo(message1), equalTo(1)); + } + + @Test + public void attachmentURLShouldBeReturnCorrectResult() throws Exception { + Message message1 = new Message(); + + assertThat(message1.getAttachmentURL(), nullValue()); + + message1.setAttachmentType("jpeg"); + + assertThat(message1.getAttachmentURL(), equalTo("http://i.juick.com/photos-1024/0.jpeg")); + + message1.setRid(1); + + assertThat(message1.getAttachmentURL(), equalTo("http://i.juick.com/photos-1024/0-1.jpeg")); + + Message message2 = new Message(); + + message2.setAttachmentType("mp4"); + + assertThat(message2.getAttachmentURL(), equalTo("http://i.juick.com/video/0.mp4")); + + message2.setRid(1); + + assertThat(message2.getAttachmentURL(), equalTo("http://i.juick.com/video/0-1.mp4")); + } + + @Test + public void tagsStringShouldBeEmptyIfNoTags() throws Exception { + Message message = new Message(); + + assertThat(message.getTagsString(), isEmptyString()); + + message.FriendsOnly = true; + + assertThat(message.getTagsString(), isEmptyString()); + + message.Hidden = true; + message.ReadOnly = true; + + assertThat(message.getTagsString(), isEmptyString()); + + message.parseTags(" "); + + assertThat(message.getTagsString(), isEmptyString()); + } + + @Test + public void tagsStringShouldHasNoTagDuplicates() throws Exception { + Message message = new Message(); + + message.parseTags("test"); + + assertThat(StringUtils.countMatches(message.getTagsString(), "*test"), equalTo(1)); + + message.parseTags("test test"); + + assertThat(StringUtils.countMatches(message.getTagsString(), "*test"), equalTo(1)); + + message.parseTags("test test ab test"); + + assertThat(StringUtils.countMatches(message.getTagsString(), "*test"), equalTo(1)); + assertThat(StringUtils.countMatches(message.getTagsString(), "*ab"), equalTo(1)); + } +} diff --git a/juick-crosspost/src/main/java/com/juick/components/Crosspost.java b/juick-crosspost/src/main/java/com/juick/components/Crosspost.java index c39898f2..c84b50f6 100644 --- a/juick-crosspost/src/main/java/com/juick/components/Crosspost.java +++ b/juick-crosspost/src/main/java/com/juick/components/Crosspost.java @@ -17,6 +17,7 @@ */ package com.juick.components; +import com.juick.Tag; import com.juick.service.CrosspostService; import org.apache.commons.codec.Charsets; import org.apache.commons.codec.binary.Base64; @@ -284,8 +285,8 @@ public class Crosspost implements AutoCloseable { public String getMessageHashTags(final com.juick.Message jmsg) { String hashtags = ""; - for (int i = 0; i < jmsg.getTags().size(); i++) { - hashtags += "#" + jmsg.getTags().get(i) + " "; + for (Tag tag : jmsg.getTags()) { + hashtags += "#" + tag + " "; } return hashtags; } diff --git a/juick-xmpp/src/main/java/com/juick/xmpp/extensions/JuickUser.java b/juick-xmpp/src/main/java/com/juick/xmpp/extensions/JuickUser.java index 7473134c..08e38c41 100644 --- a/juick-xmpp/src/main/java/com/juick/xmpp/extensions/JuickUser.java +++ b/juick-xmpp/src/main/java/com/juick/xmpp/extensions/JuickUser.java @@ -17,18 +17,17 @@ */ package com.juick.xmpp.extensions; +import com.juick.xmpp.StanzaChild; import com.juick.xmpp.utils.XmlUtils; -import com.juick.xmpp.*; -import java.io.IOException; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; +import java.io.IOException; + /** - * * @author Ugnich Anton */ public class JuickUser extends com.juick.User implements StanzaChild { - public final static String XMLNS = "http://juick.com/user"; public final static String TagName = "user"; @@ -57,15 +56,19 @@ public class JuickUser extends com.juick.User implements StanzaChild { } public static String toString(com.juick.User user) { - String str = "<" + TagName + " xmlns='" + XMLNS + "'"; - if (user.getUid() > 0) { - str += " uid='" + user.getUid() + "'"; - } - if (user.getName() != null && user.getName().length() > 0) { - str += " uname='" + XmlUtils.escape(user.getName()) + "'"; - } - str += "/>"; - return str; + StringBuilder builder = new StringBuilder(); + + builder.append("<").append(TagName).append(" xmlns='").append(XMLNS).append("'"); + + if (user.getUid() > 0) + builder.append(" uid='").append(user.getUid()).append("'"); + + if (user.getName() != null && user.getName().length() > 0) + builder.append(" uname='").append(XmlUtils.escape(user.getName())).append("'"); + + builder.append("/>"); + + return builder.toString(); } @Override -- cgit v1.2.3