commit afe07d8efd4dc94b9dfb9b5896002286ba71dc6d Author: iwakeh iwakeh@torproject.org Date: Fri Oct 27 17:35:16 2017 +0000
Add a finalized state to DescriptorBuilder.
To avoid possible inconsistencies DescriptorBuilder is finalized after the first call to 'toString' and cannot be altered anymore. Any attempt to add more leads to an IllegalStateException. --- .../collector/bridgedescs/DescriptorBuilder.java | 34 ++++++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-)
diff --git a/src/main/java/org/torproject/collector/bridgedescs/DescriptorBuilder.java b/src/main/java/org/torproject/collector/bridgedescs/DescriptorBuilder.java index 4ca9dd1..9c47b5e 100644 --- a/src/main/java/org/torproject/collector/bridgedescs/DescriptorBuilder.java +++ b/src/main/java/org/torproject/collector/bridgedescs/DescriptorBuilder.java @@ -12,25 +12,43 @@ import java.util.stream.Collectors; * <p>This builder class can be used while parsing and processing an original * descriptor. It accepts {@code String}s, {@code DescriptorBuilder}s and * {@code StringBuilder}s. The latter two as placeholders for parts that can - * only be processed after finishing the parsing step.</p> */ + * only be processed after finishing the parsing step.</p> + * + * <p>Calling {@code toString} finalizes the builder and any subsequent + * method calls other than {@code toString} will result in an + * {@code IllegalStateException}. + */ class DescriptorBuilder {
private List<Object> parts;
private StringBuilder lastPart;
+ private boolean finalized = false; + + private String value; + public DescriptorBuilder() { this.parts = new ArrayList<>(); this.lastPart = new StringBuilder(); this.parts.add(this.lastPart); }
+ private void throwExceptionIfFinalized() { + if (this.finalized) { + throw new IllegalStateException("This DescriptorBuilder is finalized and" + + " calling anything other than 'toString' is illegal."); + } + } + public DescriptorBuilder append(String sanitizedString) { + this.throwExceptionIfFinalized(); this.lastPart.append(sanitizedString); return this; }
public DescriptorBuilder append(StringBuilder placeholder) { + this.throwExceptionIfFinalized(); this.parts.add(placeholder); this.lastPart = new StringBuilder(); this.parts.add(this.lastPart); @@ -38,6 +56,7 @@ class DescriptorBuilder { }
public DescriptorBuilder append(DescriptorBuilder placeholder) { + this.throwExceptionIfFinalized(); this.parts.add(placeholder); this.lastPart = new StringBuilder(); this.parts.add(this.lastPart); @@ -45,18 +64,27 @@ class DescriptorBuilder { }
public DescriptorBuilder space() { + this.throwExceptionIfFinalized(); this.lastPart.append(' '); return this; }
public DescriptorBuilder newLine() { + this.throwExceptionIfFinalized(); this.lastPart.append('\n'); return this; }
@Override public String toString() { - return this.parts.stream().map(part -> part.toString()) - .collect(Collectors.joining("")); + if (!this.finalized) { + this.finalized = true; + this.value = this.parts.stream().map(part -> part.toString()) + .collect(Collectors.joining("")); + this.parts.clear(); // not needed anymore + this.lastPart = null; + } + return value; } + }