⌛⌛ JSON

JSON is a system independent file format to store data and to transfer data between systems. If you are not yet familiar with JSON, you can learn more, for example, from Wikipedia.

JSON data consists of following types of data items:

  • Number. In this task type double.

  • Truth value. In this task type boolean.

  • String. In this task type String.

  • Null. In this task the null reference.

  • Array. An ordered list that may contain zero or more JSON data items.

  • Object. A dictionary type structure that may contain zero or more key–item pairs. The keys are strings.

In this task, you will familiarise yourself with JSON by implementing a class hierarchy for JSON data items. The readily provided Node.java contains an abstract class Node that acts as the base class for JSON data items. This class is available at the remote material repository (round7/json/Node.java). The class Node provides functions isValue, isArray and isObject for inspecting the Node type and function printJson for the printing of the data items.

You need to implement concrete subclasses ValueNode, ArrayNode and ObjectNode that inherit Node. The exercise is returned as a Maven project. Place the pom.xml file in the round7/json directory of your local repository and create to this directory the src/main/java subdirectory. Create class files ArrayNode.java, ObjectNode.java and ValueNode.java and attach them to the fi.tuni.prog3.json package. Your files should be in the round7/json/src/main/java/fi/tuni/prog3/json directory.

Implement the classes as follows:

  • ValueNode stores a number, truth value, string or null. Public members:

    • Default constructor ValueNode() that initialises the object by storing the null in the object.

    • Constructors ValueNode(double value), ValueNode(boolean value) and ValueNode(String value) initialize the object to store the value of the corresponding type. It is assumed that null is not passed as a parameter value to the ValueNode(String value) constructor.

    • Member functions isNumber(), isBoolean(), isString() and isNull() that return truth values indicating whether the stored value is of the corresponding type or not. For example, isString returns true, if and only if the stored value is a string.

    • Member functions double getNumber(), boolean getBoolean(), String getString() and Object getNull() that return the corresponding value. For example getBoolean returns the value stored by the object as a boolean, and it is the responsibility of the caller to first call isBoolean to check that the value really can be returned as a truth value.

  • The ArrayNode class stores Node objects. Properties and public members:

    • Implements the interface Iterable<Node>.

    • A default constructor that initializes an empty array that does not contain any Node objects yet.

    • Member function void add(Node node) that adds Node to the end of the array.

    • Member function int size() that returns the number of stored Node objects.

  • ObjectNode that stores key–value pairs, where keys are strings and values are Node objects. Properties and public members:

    • Implements the interface Iterable<String>. Iterates over the keys of the stored key–value pairs in the natural sorted order of String.

    • A default constructor that initializes an empty JSON object that does not have any key-value pairs yet.

    • Member function Node get(String key) that returns the Node object corresponding to key, or null if the key does not exist. Please note that the “plain” null is here an error code, while a ValueNode containing the null value is a valid return value.

    • Member function void set(String key, Node node) that adds a key–value pair described by the parameters. A possible earlier value for the key will be overwritten.

    • Member function int size() that returns the number of stored Node objects.

The implementations of ArrayNode and ObjectNode can be simple, if you use the Java containers wisely.

The automatic tests, and the ones given below, assume that you make the following definitions in your pom.xml project file:

  • The value of artifactId is json.

  • The value of version is 1.0.

  • The values of the maven.compiler.source and maven.compiler.target elements are 17 or lower. The grader uses Java 17, so any newer versions won’t work.

  • A Onejar plugin definition where the value of mainClass is JsonTest which is the name of the given test class (see below).

Testing

You may test your implementation by using the test program given in the file JsonTest.java and the example output given in the files output1.txt, output2.txt, output3.txt and output4.txt.

Place JsonTest.java into the root of the src/main/java subdirectory of your Maven project, and the other files into the root directory of your Maven project, that is, where the pom.xml is. Note that JsonTest.java does not include a package definition and therefore is not placed into a deeper subdirectory.

After this you can compile the program with mvn package and run the tests as java -jar target/json-1.0.one-jar.jar 1, java -jar target/json-1.0.one-jar.jar 2, java -jar target/json-1.0.one-jar.jar 3 and java -jar target/json-1.0.one-jar.jar 4 in the root directory of the project. The expected outputs of these four tests are given in the files output1.txt, output2.txt, output3.txt and output4.txt.

A+ presents the exercise submission form here.