+ public static Optional<NextLink> findNextLink(String line) {
+ int earliestLinkPosition = Integer.MAX_VALUE;
+ NextLink earliestNextLink = null;
+ for (LinkType possibleLinkType : LinkType.values()) {
+ Optional<NextLink> nextLink = possibleLinkType.findNext(line);
+ if (nextLink.isPresent()) {
+ if (nextLink.get().getPosition() < earliestLinkPosition) {
+ earliestNextLink = nextLink.get();
+ earliestLinkPosition = earliestNextLink.getPosition();
+ }
+ }
+ }
+ return Optional.fromNullable(earliestNextLink);
+ }
+
+ private void renderSoneLink(List<Part> parts, String line) {
+ if (line.length() >= (7 + 43)) {
+ String soneId = line.substring(7, 50);
+ Optional<Sone> sone = soneProvider.getSone(soneId);
+ parts.add(new SonePart(sone.or(new IdOnlySone(soneId))));
+ } else {
+ parts.add(new PlainTextPart(line));
+ }
+ }
+
+ private void renderPostLink(List<Part> parts, String line) {
+ if (line.length() >= (7 + 36)) {
+ String postId = line.substring(7, 43);
+ Optional<Post> post = postProvider.getPost(postId);
+ if (post.isPresent()) {
+ parts.add(new PostPart(post.get()));
+ } else {
+ parts.add(new PlainTextPart(line.substring(0, 43)));
+ }
+ } else {
+ parts.add(new PlainTextPart(line));
+ }
+ }
+
+ private void renderFreenetLink(List<Part> parts, String link, LinkType linkType, @Nullable SoneTextParserContext context) {
+ String name = link;
+ String linkWithoutParameters = link;
+ if (name.indexOf('?') > -1) {
+ linkWithoutParameters = name = name.substring(0, name.indexOf('?'));
+ }
+ if (name.endsWith("/")) {
+ name = name.substring(0, name.length() - 1);
+ }
+ try {
+ FreenetURI uri = new FreenetURI(name);
+ name = uri.lastMetaString();
+ if (name == null) {
+ name = uri.getDocName();
+ }
+ if (name == null) {
+ name = link.substring(0, Math.min(9, link.length()));
+ }
+ boolean fromPostingSone = ((linkType == LinkType.SSK) || (linkType == LinkType.USK)) && (context != null) && (context.getPostingSone() != null) && link.substring(4, Math.min(link.length(), 47)).equals(context.getPostingSone().getId());
+ parts.add(new FreenetLinkPart(link, name, linkWithoutParameters, fromPostingSone));
+ } catch (MalformedURLException mue1) {
+ /* not a valid link, insert as plain text. */
+ parts.add(new PlainTextPart(link));
+ } catch (NullPointerException npe1) {
+ /* FreenetURI sometimes throws these, too. */
+ parts.add(new PlainTextPart(link));
+ } catch (ArrayIndexOutOfBoundsException aioobe1) {
+ /* oh, and these, too. */
+ parts.add(new PlainTextPart(link));
+ }
+ }
+
+ private void renderHttpLink(List<Part> parts, String link, LinkType linkType) {
+ String name = link.substring(linkType == LinkType.HTTP ? 7 : 8);
+ int firstSlash = name.indexOf('/');
+ int lastSlash = name.lastIndexOf('/');
+ if ((lastSlash - firstSlash) > 3) {
+ name = name.substring(0, firstSlash + 1) + "…" + name.substring(lastSlash);
+ }
+ if (name.endsWith("/")) {
+ name = name.substring(0, name.length() - 1);
+ }
+ if (((name.indexOf('/') > -1) && (name.indexOf('.') < name.lastIndexOf('.', name.indexOf('/'))) || ((name.indexOf('/') == -1) && (name.indexOf('.') < name.lastIndexOf('.')))) && name.startsWith("www.")) {
+ name = name.substring(4);
+ }
+ if (name.indexOf('?') > -1) {
+ name = name.substring(0, name.indexOf('?'));
+ }
+ parts.add(new LinkPart(link, name));
+ }
+
+ private void renderFreemailLink(List<Part> parts, String line) {
+ int separator = line.indexOf('@');
+ String freemailId = line.substring(separator + 1, separator + 53);
+ String identityId = Base64.encode(Base32.decode(freemailId));
+ String emailLocalPart = line.substring(0, separator);
+ parts.add(new FreemailPart(emailLocalPart, freemailId, identityId));
+ }
+
+ private static boolean isPunctuation(char character) {
+ return (character == '.') || (character == ',') || (character == '!') || (character == '?');
+ }
+