From ffc9abb55f98b336377b51870cc8093e670bcdf4 Mon Sep 17 00:00:00 2001 From: amihaiemil Date: Mon, 13 Feb 2017 10:46:13 +0200 Subject: [PATCH] Yaml lines design --- .../com/amihaiemil/camel/RtYamlInput.java | 36 ++++++- .../java/com/amihaiemil/camel/RtYamlLine.java | 96 +++++++++++++++++++ .../java/com/amihaiemil/camel/YamlLine.java | 58 +++++++++++ .../java/com/amihaiemil/camel/YamlLines.java | 60 ++++++++++++ .../com/amihaiemil/camel/YamlObjectDump.java | 4 +- 5 files changed, 247 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/amihaiemil/camel/RtYamlLine.java create mode 100644 src/main/java/com/amihaiemil/camel/YamlLine.java create mode 100644 src/main/java/com/amihaiemil/camel/YamlLines.java diff --git a/src/main/java/com/amihaiemil/camel/RtYamlInput.java b/src/main/java/com/amihaiemil/camel/RtYamlInput.java index 0659bbae..d6cbc8b7 100644 --- a/src/main/java/com/amihaiemil/camel/RtYamlInput.java +++ b/src/main/java/com/amihaiemil/camel/RtYamlInput.java @@ -27,26 +27,32 @@ */ package com.amihaiemil.camel; +import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; /** * Implementation for {@link YamlInput}. * @author Mihai Andronache (amihaiemil@gmail.com) * @version $Id$ * @since 1.0.0 - * @todo #46:30m Finish implementing this class using a finite automata. - * Short idea: using an InputStreamReader, read each char from the stream, - * see if the automata accepts it. If it's accepted, build the yaml. */ final class RtYamlInput implements YamlInput { + /** + * Source of the input. + */ + private InputStream source; + /** * Ctor. * @param source Given source. */ RtYamlInput(final InputStream source) { - new InputStreamReader(source); + this.source = source; } @Override @@ -58,4 +64,26 @@ public YamlMapping readYamlMapping() { public YamlSequence readYamlSequence() { return null; } + + /** + * Read the input's lines. + * @return YamlLines + * @throws IOException If something goes wrong while reading the input. + */ + private YamlLines readInput() throws IOException { + Queue lines = new ConcurrentLinkedQueue<>(); + try ( + BufferedReader reader = new BufferedReader( + new InputStreamReader(this.source) + ) + ) { + String line; + int number = 0; + while ((line = reader.readLine()) != null) { + lines.add(new RtYamlLine(line, number)); + number++; + } + } + return null; + } } diff --git a/src/main/java/com/amihaiemil/camel/RtYamlLine.java b/src/main/java/com/amihaiemil/camel/RtYamlLine.java new file mode 100644 index 00000000..726f1c2a --- /dev/null +++ b/src/main/java/com/amihaiemil/camel/RtYamlLine.java @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2016-2017, Mihai Emil Andronache + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +package com.amihaiemil.camel; + +/** + * Default implementation of {@link YamlLine}. + * @author Mihai Andronache (amihaiemil@gmail.com) + * @version $Id$ + * @since 1.0.0 + * @todo #52:30min Right now, at every call of trimmed() and indentation() + * the values are calculated. This isn't efficient, so we need a decorator + * to cache these values. Let's name it CachedYamlLine. It should be used + * like this: YamlLine line = new CachedYamlLine(new RtYamlLine(...)); + * @todo #52:30min Method indentation() also checks that the value is multiple + * of 2. We should extract this in a decorator called WellIndentedLine which + * will also check if the intendetaion is correct relative to the previous + * line. It would be used like this:
+ * YamlLine line = new WellINdentedLine(line, previousLine). + */ +final class RtYamlLine implements YamlLine { + + /** + * Content. + */ + private String value; + + /** + * Line nr. + */ + private int number; + + /** + * Ctor. + * @param value Contents of this line. + * @param number Number of the line. + */ + RtYamlLine(final String value, final int number) { + this.value = value; + this.number = number; + } + + @Override + public String trimmed() { + return this.value.trim(); + } + + @Override + public int number() { + return this.number; + } + + @Override + public int indentation() { + int indentation = 0; + int index = 0; + while (index < this.value.length()) { + if (this.value.charAt(index) == ' ') { + indentation++; + } + index++; + } + if (indentation % 2 != 0) { + throw new IllegalStateException( + "Indentation of line " + this.number + " is not correct. " + + "It is " + indentation + " and it should be a multiple of 2!" + ); + } + return indentation; + } + +} diff --git a/src/main/java/com/amihaiemil/camel/YamlLine.java b/src/main/java/com/amihaiemil/camel/YamlLine.java new file mode 100644 index 00000000..c9b36d88 --- /dev/null +++ b/src/main/java/com/amihaiemil/camel/YamlLine.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2016-2017, Mihai Emil Andronache + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +package com.amihaiemil.camel; + +/** + * A line of yaml. + * @author Mihai Andronache (amihaiemil@gmail.com) + * @version $Id$ + * @since 1.0.0 + * + */ +interface YamlLine { + + /** + * The line's trimmed contents. + * @return String contents. + */ + String trimmed(); + + /** + * Number of the line (count start from 0). + * @return Integer. + */ + int number(); + + /** + * This line's indentation (number of spaces at the beginning of it).>br> + * Should be a multiple of 2! If not, IllegalStateException is thrown. + * @return Integer. + * @throws IllegalStateException if the indentation is not multiple of 2. + */ + int indentation(); +} diff --git a/src/main/java/com/amihaiemil/camel/YamlLines.java b/src/main/java/com/amihaiemil/camel/YamlLines.java new file mode 100644 index 00000000..347c9a14 --- /dev/null +++ b/src/main/java/com/amihaiemil/camel/YamlLines.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2016-2017, Mihai Emil Andronache + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +package com.amihaiemil.camel; + +/** + * Iterable yaml lines. + * @author Mihai Andronache (amihaiemil@gmail.com) + * @version $Id$ + * @since 1.0.0 + * @todo #52:1h Implement and unit test this interface. It should + * be named RtYamlLines and be a default-accessible class. + */ +interface YamlLines extends Iterable { + + /** + * Lines which are contained within the current YamlLine (lines which are + *
indented by 2 or more spaces beneath it). + * @return YamlLines + */ + YamlLines contained(); + + /** + * Turn these lines into a Yaml mapping. + * @return YamlMapping. + */ + YamlMapping toYamlMapping(); + + /** + * Turn these lines into a Yaml sequence. + * @return YamlSequence. + */ + YamlSequence toYamlSequence(); + + +} diff --git a/src/main/java/com/amihaiemil/camel/YamlObjectDump.java b/src/main/java/com/amihaiemil/camel/YamlObjectDump.java index e363628e..77c032ae 100644 --- a/src/main/java/com/amihaiemil/camel/YamlObjectDump.java +++ b/src/main/java/com/amihaiemil/camel/YamlObjectDump.java @@ -81,15 +81,13 @@ public YamlMapping represent() { * Convert a complex property to a Yaml node. * @param property The property to represent as a YamlNode * @return YamlNode representation of - * @todo #34:30m/DEV After YamlMapDump and YamlCollectionDump are - * implemented, this method should be fixed. */ private YamlNode yamlNode(final Object property) { YamlNode node; if (property instanceof Map) { node = new YamlMapDump((Map) property).represent(); } else if (property instanceof Collection) { - node = new Scalar("...yaml sequence..."); + node = new YamlCollectionDump((Collection) property).represent(); } else { node = new YamlObjectDump(property).represent(); }