From a50ce8a4da6ec513a97a2d0237e8ef9f640283cd Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Thu, 10 Nov 2016 21:34:54 +0100 Subject: [PATCH] Remove part container --- .../net/pterodactylus/sone/text/PartContainer.java | 128 --------------------- .../pterodactylus/sone/text/SoneTextParser.java | 18 +-- .../pterodactylus/sone/text/PartContainerTest.java | 99 ---------------- .../sone/template/RenderFilterTest.kt | 7 +- 4 files changed, 12 insertions(+), 240 deletions(-) delete mode 100644 src/main/java/net/pterodactylus/sone/text/PartContainer.java delete mode 100644 src/test/java/net/pterodactylus/sone/text/PartContainerTest.java diff --git a/src/main/java/net/pterodactylus/sone/text/PartContainer.java b/src/main/java/net/pterodactylus/sone/text/PartContainer.java deleted file mode 100644 index 3444d19..0000000 --- a/src/main/java/net/pterodactylus/sone/text/PartContainer.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Sone - PartContainer.java - Copyright © 2010–2016 David Roden - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.pterodactylus.sone.text; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Objects; - -import javax.annotation.Nonnull; - -/** - * Part implementation that can contain an arbitrary amount of other parts. - * Parts are added using the {@link #add(Part)} method and will be rendered in - * the order they are added. - * - * @author David ‘Bombe’ Roden - */ -public class PartContainer implements Part, Iterable { - - private final List parts = new ArrayList(); - - public void add(@Nonnull Part part) { - parts.add(Objects.requireNonNull(part)); - } - - @Nonnull - public Part getPart(int index) { - return parts.get(index); - } - - public void removePart(int index) { - parts.remove(index); - } - - public int size() { - return parts.size(); - } - - @Override - @Nonnull - public String getText() { - StringBuilder partText = new StringBuilder(); - for (Part part : parts) { - partText.append(part.getText()); - } - return partText.toString(); - } - - @Override - @Nonnull - @SuppressWarnings("synthetic-access") - public Iterator iterator() { - return new Iterator() { - - private Deque> partStack = new ArrayDeque>(); - private Part nextPart; - private boolean foundNextPart; - private boolean noNextPart; - - { - partStack.push(parts.iterator()); - } - - private void findNext() { - if (foundNextPart) { - return; - } - noNextPart = true; - while (!partStack.isEmpty()) { - Iterator parts = partStack.pop(); - if (parts.hasNext()) { - nextPart = parts.next(); - partStack.push(parts); - if (nextPart instanceof PartContainer) { - partStack.push(((PartContainer) nextPart).iterator()); - } else { - noNextPart = false; - break; - } - } - } - foundNextPart = true; - } - - @Override - public boolean hasNext() { - findNext(); - return !noNextPart; - } - - @Override - public Part next() { - findNext(); - if (noNextPart) { - throw new NoSuchElementException(); - } - foundNextPart = false; - return nextPart; - } - - @Override - public void remove() { - /* ignore. */ - } - - }; - } - -} diff --git a/src/main/java/net/pterodactylus/sone/text/SoneTextParser.java b/src/main/java/net/pterodactylus/sone/text/SoneTextParser.java index a279a6d..c3c4068 100644 --- a/src/main/java/net/pterodactylus/sone/text/SoneTextParser.java +++ b/src/main/java/net/pterodactylus/sone/text/SoneTextParser.java @@ -26,6 +26,8 @@ import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; @@ -223,7 +225,7 @@ public class SoneTextParser implements Parser { @Nonnull @Override public Iterable parse(@Nonnull String source, @Nullable SoneTextParserContext context) { - PartContainer parts = new PartContainer(); + List parts = new ArrayList<>(); try (Reader sourceReader = new StringReader(source); BufferedReader bufferedReader = new BufferedReader(sourceReader)) { String line; @@ -315,11 +317,11 @@ public class SoneTextParser implements Parser { throw new RuntimeException(ioe1); } for (int partIndex = parts.size() - 1; partIndex >= 0; --partIndex) { - Part part = parts.getPart(partIndex); + Part part = parts.get(partIndex); if (!(part instanceof PlainTextPart) || !"\n".equals(part.getText())) { break; } - parts.removePart(partIndex); + parts.remove(partIndex); } return parts; } @@ -338,7 +340,7 @@ public class SoneTextParser implements Parser { return Optional.fromNullable(earliestNextLink); } - private void renderSoneLink(PartContainer parts, String line) { + private void renderSoneLink(List parts, String line) { if (line.length() >= (7 + 43)) { String soneId = line.substring(7, 50); Optional sone = soneProvider.getSone(soneId); @@ -348,7 +350,7 @@ public class SoneTextParser implements Parser { } } - private void renderPostLink(PartContainer parts, String line) { + private void renderPostLink(List parts, String line) { if (line.length() >= (7 + 36)) { String postId = line.substring(7, 43); Optional post = postProvider.getPost(postId); @@ -362,7 +364,7 @@ public class SoneTextParser implements Parser { } } - private void renderFreenetLink(PartContainer parts, String link, LinkType linkType, @Nullable SoneTextParserContext context) { + private void renderFreenetLink(List parts, String link, LinkType linkType, @Nullable SoneTextParserContext context) { String name = link; String linkWithoutParameters = link; if (name.indexOf('?') > -1) { @@ -394,7 +396,7 @@ public class SoneTextParser implements Parser { } } - private void renderHttpLink(PartContainer parts, String link, LinkType linkType) { + private void renderHttpLink(List parts, String link, LinkType linkType) { String name = link.substring(linkType == LinkType.HTTP ? 7 : 8); int firstSlash = name.indexOf('/'); int lastSlash = name.lastIndexOf('/'); @@ -413,7 +415,7 @@ public class SoneTextParser implements Parser { parts.add(new LinkPart(link, name)); } - private void renderFreemailLink(PartContainer parts, String line) { + private void renderFreemailLink(List parts, String line) { int separator = line.indexOf('@'); String freemailId = line.substring(separator + 1, separator + 53); String identityId = Base64.encode(Base32.decode(freemailId)); diff --git a/src/test/java/net/pterodactylus/sone/text/PartContainerTest.java b/src/test/java/net/pterodactylus/sone/text/PartContainerTest.java deleted file mode 100644 index 036b2dc..0000000 --- a/src/test/java/net/pterodactylus/sone/text/PartContainerTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package net.pterodactylus.sone.text; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -import org.junit.Test; - -/** - * Unit test for {@link PartContainer}. - * - * @author David ‘Bombe’ Roden - */ -public class PartContainerTest { - - private final PartContainer container = new PartContainer(); - - @Test - public void emptyContainerHasSizeZero() { - assertThat(container.size(), is(0)); - } - - @Test(expected = NullPointerException.class) - public void canNotAddNullPart() { - container.add(null); - } - - @Test - public void containerWithSinglePartHasSizeOne() { - container.add(mock(Part.class)); - assertThat(container.size(), is(1)); - } - - @Test - public void containerWithSinglePartCanReturnPart() { - Part part = mock(Part.class); - container.add(part); - assertThat(container.getPart(0), is(part)); - } - - @Test - public void containerIsEmptyAfterPartIsAddedAndRemoved() { - container.add(mock(Part.class)); - container.removePart(0); - assertThat(container.size(), is(0)); - } - - @Test - public void containerContainsSecondPartIfFirstPartIsRemoved() { - container.add(mock(Part.class)); - Part part = mock(Part.class); - container.add(part); - container.removePart(0); - assertThat(container.getPart(0), is(part)); - } - - @Test - public void textOfContainerPartIsTextOfPartsConcatenated() { - container.add(createPartWithText("first")); - container.add(createPartWithText("second")); - assertThat(container.getText(), is("firstsecond")); - } - - private Part createPartWithText(String text) { - Part part = mock(Part.class); - when(part.getText()).thenReturn(text); - return part; - } - - @Test(expected = NoSuchElementException.class) - public void emptyContainerIteratorThrowsOnNext() { - container.iterator().next(); - } - - @Test - public void iteratorIteratesPartsRecursivelyInCorrectOrder() { - Part firstPart = mock(Part.class); - PartContainer secondPart = new PartContainer(); - Part thirdPart = mock(Part.class); - Part nestedFirstPart = mock(Part.class); - Part nestedSecondPart = mock(Part.class); - secondPart.add(nestedFirstPart); - secondPart.add(nestedSecondPart); - container.add(firstPart); - container.add(secondPart); - container.add(thirdPart); - Iterator parts = container.iterator(); - assertThat(parts.next(), is(firstPart)); - assertThat(parts.next(), is(nestedFirstPart)); - assertThat(parts.next(), is(nestedSecondPart)); - assertThat(parts.next(), is(thirdPart)); - assertThat(parts.hasNext(), is(false)); - } - -} diff --git a/src/test/kotlin/net/pterodactylus/sone/template/RenderFilterTest.kt b/src/test/kotlin/net/pterodactylus/sone/template/RenderFilterTest.kt index af74531..fbafdaf 100644 --- a/src/test/kotlin/net/pterodactylus/sone/template/RenderFilterTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/template/RenderFilterTest.kt @@ -10,7 +10,6 @@ import net.pterodactylus.sone.text.FreemailPart import net.pterodactylus.sone.text.FreenetLinkPart import net.pterodactylus.sone.text.LinkPart import net.pterodactylus.sone.text.Part -import net.pterodactylus.sone.text.PartContainer import net.pterodactylus.sone.text.PlainTextPart import net.pterodactylus.sone.text.PostPart import net.pterodactylus.sone.text.SonePart @@ -209,10 +208,8 @@ class RenderFilterTest { @Test fun `multiple parts are rendered correctly`() { - val parts = PartContainer() - parts.add(PlainTextPart("te")) - parts.add(PlainTextPart("xt")) - assertThat(renderParts(parts), `is`("text")) + val parts = arrayOf(PlainTextPart("te"), PlainTextPart("xt")) + assertThat(renderParts(*parts), `is`("text")) } @Test -- 2.7.4