diff options
Diffstat (limited to 'src/main/java/com/juick/util/MessageUtils.java')
-rw-r--r-- | src/main/java/com/juick/util/MessageUtils.java | 78 |
1 files changed, 47 insertions, 31 deletions
diff --git a/src/main/java/com/juick/util/MessageUtils.java b/src/main/java/com/juick/util/MessageUtils.java index cc0d7b12..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; @@ -87,36 +93,36 @@ public class MessageUtils { private final static String underlineRegex = "((?<=\\s)|(?<=\\A))_([^\\_\\n<>]+)_((?=\\s)|(?=\\Z)|(?=\\p{Punct}))"; - private final static String citateRegex = "(?:(?<=\\n)|(?<=\\A))\\> *(.*)?(\\n|(?=\\Z))"; + private final static String citateRegex = "(?:(?<=\\n)|(?<=\\A))(?:>|>) *(.*)?(\\n|(?=\\Z))"; public static List<Entity> getEntities(Message msg) { String txt = msg.getText(); // http://juick.com/last?page=2 - List<Entity> result = new ArrayList<>(entitiesForType("a", txt, urlWithWhitespacesRegex, matcher -> matcher.group(3), matcher -> Optional.of(matcher.group(2)))); + List<Entity> result = new ArrayList<>(entitiesForType("a", txt, urlWithWhitespacesRegex, matcher -> matcher.group(3), matcher -> Optional.of(matcher.group(2)), 0)); // [link text][http://juick.com/last?page=2] - result.addAll(entitiesForType("a", txt, textUrlRegex, matcher -> matcher.group(1), matcher -> Optional.of(matcher.group(2)))); + result.addAll(entitiesForType("a", txt, textUrlRegex, matcher -> matcher.group(1), matcher -> Optional.of(matcher.group(2)), 0)); // [link text](http://juick.com/last?page=2) - result.addAll(entitiesForType("a", txt, textUrlRegex2, matcher -> matcher.group(1), matcher -> Optional.of(matcher.group(2)))); + result.addAll(entitiesForType("a", txt, textUrlRegex2, matcher -> matcher.group(1), matcher -> Optional.of(matcher.group(2)), 0)); // #12345 - result.addAll(entitiesForType("a", txt, midRegex, matcher -> String.format("#%s", matcher.group(2)), matcher -> Optional.of("https://juick.com/m/" + matcher.group(2)))); + result.addAll(entitiesForType("a", txt, midRegex, matcher -> String.format("#%s", matcher.group(2)), matcher -> Optional.of("https://juick.com/m/" + matcher.group(2)), 0)); // #12345/65 - result.addAll(entitiesForType("a", txt, ridRegex, matcher -> String.format("#%s/%s", matcher.group(2), matcher.group(3)), matcher -> Optional.of(String.format("https://juick.com/m/%s#%s", matcher.group(2), matcher.group(3))))); + result.addAll(entitiesForType("a", txt, ridRegex, matcher -> String.format("#%s/%s", matcher.group(2), matcher.group(3)), matcher -> Optional.of(String.format("https://juick.com/m/%s#%s", matcher.group(2), matcher.group(3))), 0)); // /12 - result.addAll(entitiesForType("a", txt, replyNumberRegex, matcher -> "/" + matcher.group(2), matcher -> Optional.of(String.format("https://juick.com/m/%d#%s", msg.getMid(), matcher.group(2))))); + result.addAll(entitiesForType("a", txt, replyNumberRegex, matcher -> "/" + matcher.group(2), matcher -> Optional.of(String.format("https://juick.com/m/%d#%s", msg.getMid(), matcher.group(2))), 0)); // @username@jabber.org - result.addAll(entitiesForType("a", txt, jidRegex, matcher -> matcher.group(2), matcher -> Optional.of(String.format("https://juick.com/%s", matcher.group(2))))); + result.addAll(entitiesForType("a", txt, jidRegex, matcher -> matcher.group(2), matcher -> Optional.of(String.format("https://juick.com/%s", matcher.group(2))), 0)); // @username - result.addAll(entitiesForType("a", txt, usernameRegex, matcher -> matcher.group(2), matcher -> Optional.of(String.format("https://juick.com/%s", matcher.group(2))))); + result.addAll(entitiesForType("a", txt, usernameRegex, matcher -> matcher.group(2), matcher -> Optional.of(String.format("https://juick.com/%s", matcher.group(2))), 0)); // *bold* - result.addAll(entitiesForType("b", txt, boldRegex, matcher -> matcher.group(2), matcher -> Optional.empty())); + result.addAll(entitiesForType("b", txt, boldRegex, matcher -> matcher.group(2), matcher -> Optional.empty(), 0)); // /italic/ - result.addAll(entitiesForType("i", txt, italicRegex, matcher -> matcher.group(2), matcher -> Optional.empty())); + result.addAll(entitiesForType("i", txt, italicRegex, matcher -> matcher.group(2), matcher -> Optional.empty(), 0)); // _underline_ - result.addAll(entitiesForType("u", txt, underlineRegex, matcher -> matcher.group(2), matcher -> Optional.empty())); + result.addAll(entitiesForType("u", txt, underlineRegex, matcher -> matcher.group(2), matcher -> Optional.empty(), 0)); // > citate - result.addAll(entitiesForType("q", txt, citateRegex, matcher -> matcher.group(1), matcher -> Optional.empty())); + result.addAll(entitiesForType("q", txt, citateRegex, matcher -> matcher.group(1), matcher -> Optional.empty(), 1)); return result; } @@ -144,6 +150,11 @@ public class MessageUtils { } public static String formatMessage(String msg) { + + msg = msg.replaceAll("&", "&"); + msg = msg.replaceAll("<", "<"); + msg = msg.replaceAll(">", ">"); + // -- // — msg = msg.replaceAll("((?<=\\s)|(?<=\\A))\\-\\-?((?=\\s)|(?=\\Z))", "$1—$2"); @@ -294,23 +305,15 @@ public class MessageUtils { public static boolean replyStartsWithQuote(Message msg) { return msg.getRid() > 0 && StringUtils.defaultString(msg.getText()).startsWith(">"); } - public static List<Tag> parseTags(String strTags) { - List<Tag> tags = new ArrayList<>(); - if (StringUtils.isNotEmpty(strTags)) { - Set<Tag> 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<Tag> 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<Tag> tags = msg.getTags(); + Set<Tag> tags = msg.getTags(); + if (!tags.isEmpty()) { for (Tag Tag : tags) builder.append(" *").append(Tag.getName()); @@ -369,7 +372,20 @@ public class MessageUtils { return collectMatches(jidPattern, msg.getText()); } - private static List<Entity> entitiesForType(String type, String input, String patternText, Function<Matcher, String> textGroup, Function<Matcher, Optional<String>> linkGroup) { + /** + * + * @param type Name of the entity + * @param input data to find matches + * @param patternText pattern to match + * @param textGroup function which return text representation + * @param linkGroup function which return link address + * @param endGroupId group id used to set end of entity (e.g. do not count linebreak as part of quote entity) + * @return list of entities + */ + private static List<Entity> entitiesForType(String type, String input, String patternText, + Function<Matcher, String> textGroup, + Function<Matcher, Optional<String>> linkGroup, + int endGroupId) { List<Entity> result = new ArrayList<>(); Pattern pattern = Pattern.compile(patternText); Matcher matcher = pattern.matcher(input); @@ -380,7 +396,7 @@ public class MessageUtils { Optional<String> link = linkGroup.apply(matcher); link.ifPresent(entity::setUrl); entity.setStart(matcher.start()); - entity.setEnd(matcher.end()); + entity.setEnd(matcher.end(endGroupId)); result.add(entity); } return result; |