Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Create a MorseCode class as described below: Preconditions The text string canno

ID: 3720818 • Letter: C

Question

Create a MorseCode class as described below:

Preconditions

The text string cannot be null. If so, the method will throw a NullPointerException

The text contains only the subset of characters contained in the provided morseCode.txt file and spaces.

If an unrecognized character is encountered, the method should throw an IllegalArgumentException with text indicating the invalid character.

Note:the class must be reentrant, that is, it must be possible for multiple threads to call the encode and decode methods simultaneously. To ensure this one cannot use store working data in class member variables since all threads will try to share the same variables

Preconditions

The code string cannot be null. If so, the method will throw a NullPointerException

If an unrecognized code is encountered, the method should throw an IllegalArgumentException with text displaying the decoded text up to the invalid code and the unrecognized code.

Note:the class must be reentrant, that is, it must be possible for multiple threads to call the encode and decode methods simultaneously. To ensure this one cannot use store working data in class member variables since all threads will try to share the same variables

Note: your solution must traverse the decodingTree when decoding.

To ensure consistency, the right children represent DOTs, the left children DASHes.

Signature Requirement Constructors N/A This is a utility class that has only static members. Since no objects will be instantiated any initialization must be done in static initializer blocks. No constructors will be activated. If you choose to load the morseCode.txt file it must be fully contained and accessible from your solution from a foreign machine. Suggested approach: place data file in a datasubdirectory in your solution package and access using the getResourceAsStream() method Methods public static String encode(String text) Translates the given text of ASCII Latin Characters to its morse code equivalent. The encoding places a space between encoded characters; a space in the text is represented as a SLASH ('/') character.
The text can be in mixed case.

Preconditions

The text string cannot be null. If so, the method will throw a NullPointerException

The text contains only the subset of characters contained in the provided morseCode.txt file and spaces.

If an unrecognized character is encountered, the method should throw an IllegalArgumentException with text indicating the invalid character.

Note:the class must be reentrant, that is, it must be possible for multiple threads to call the encode and decode methods simultaneously. To ensure this one cannot use store working data in class member variables since all threads will try to share the same variables

public static String decode(String code) Decodes the provided code string to its text representation. Since Morse Code is case-less, the returned string will be in all UPPER CASE characters.

Preconditions

The code string cannot be null. If so, the method will throw a NullPointerException

The code string contains only DOTs ('*'), DASHes('-'), spaces that separate characters, and SLASHes('/') that represent spaces in the original text.

If an unrecognized code is encountered, the method should throw an IllegalArgumentException with text displaying the decoded text up to the invalid code and the unrecognized code.

Note:the class must be reentrant, that is, it must be possible for multiple threads to call the encode and decode methods simultaneously. To ensure this one cannot use store working data in class member variables since all threads will try to share the same variables

Note: your solution must traverse the decodingTree when decoding.

public static Map<Character, String> getEncodingMap() Returns the mapping of encodings from each character to its morse code representation. public static TreeNode<Character> getDecodingTree() Returns the root node of the binary tree used to decode a code string containing DOTs, DASHes, SLASHes, and space characters to its character representation

To ensure consistency, the right children represent DOTs, the left children DASHes.

Explanation / Answer

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class MorseCode {

    public static String encode(String text) {
        Map<Character, String> map = getEncodingMap();
        text = text.toUpperCase();
        StringBuilder encoded = new StringBuilder();
        if (text != null) {
            char[] charaters = text.toCharArray();
            for (char i : charaters) {
                if (map.containsKey(i))
                    encoded.append(map.get(i) + " ");
                else if (i == ' ') {
                    encoded.setLength(encoded.length() - 1);
                    encoded.append("/");
                } else
                    throw new IllegalArgumentException(encoded + "Unrecognised character:" + i);
            }
        } else
            throw new NullPointerException();
        encoded.setLength(encoded.length() - 1);
        return encoded.toString();
    }

    // Returns the mapping of encodings from each character to its morse code representation.

    public static Map<Character, String> getEncodingMap() {
        Map<Character, String> map = new HashMap<Character, String>();
        final String filePath = "/data/morseCode.txt";
        final InputStream inputFile = MorseCode.class.getResourceAsStream(filePath);
        final Scanner input = new Scanner(inputFile);
        while (input.hasNextLine()) {
            String characterString = input.next();
            Character character = characterString.charAt(0);
            String string = input.next();
            map.put(character, string);
        }
        input.close();
        return map;
    }

    // Decodes a Morse code string to UPPER CASE ASCII Characters.

    public static String decode(String code) {
        StringBuilder validMorse = new StringBuilder();
        final String filePath = "/data/morseCode.txt";
        final InputStream inputFile = MorseCode.class.getResourceAsStream(filePath);
        final Scanner input = new Scanner(inputFile);
        while (input.hasNextLine()) {
            input.next();
            String string = input.next();
            validMorse.append(string + " ");
        }
        input.close();
        StringBuilder decode = new StringBuilder();
        if (code != null) {
            String[] morse = code.split(" ");
            for (String i : morse) {
                if (validMorse.indexOf(i) >= 0)
                    decode.append(decoder(i));
                else if (i.equals("/"))
                    decode.append(" ");
                else
                    throw new IllegalArgumentException(decode + " Unrecognised string:" + i);
            }
        } else
            throw new NullPointerException();
        decode.setLength(decode.length() - 1);
        return decode.toString();
    }

    // Decodes a Morse code value string into its character value.

    private static Character decoder(String string) {
        DecodingTree decodeTree = new DecodingTree();
        final String filePath = "/data/morseCode.txt";
        final InputStream inputFile = MorseCode.class.getResourceAsStream(filePath);
        final Scanner input = new Scanner(inputFile);
        while (input.hasNextLine()) {
            String characterValue = input.next();
            Character character = characterValue.charAt(0);
            String code = input.next();
            decodeTree.insert(character, code);
        }
        TreeNode<Character> root = getDecodingTree();
        decodeTree.preorder(root);
        StringBuilder decode = new StringBuilder("x");
        int i = 1;
        if (string.charAt(i - 1) == '-') {
            if (string.length() == i)
                decode.append(root.getLeftChild().getValue());
            else
                decode.append(decoder(root.getLeftChild(), string, i));
        } else if (string.charAt(i - 1) == '*') {
            if (string.length() == i) {
                if (root.getRightChild() != null)
                    decode.append(root.getRightChild().getValue());
            } else
                decode.append(decoder(root.getRightChild(), string, i));
        }
        return decode.charAt(0);
    }

    // Compares the parentNode's Child values to the morse string recursively.

    private static char decoder(TreeNode<Character> parentNode, String string, int i) {
        StringBuilder decoder = new StringBuilder();
        while (parentNode != null) {
            i++;
            if (string.charAt(i - 1) == '-') {
                if (string.length() == i) {
                    decoder.append((parentNode.getLeftChild()).getValue());

                } else
                    decoder(parentNode.getLeftChild(), string, i);

            } else if (string.charAt(i - 1) == '*') {
                if (string.length() == i) {
                    decoder.append((parentNode.getRightChild()).getValue());

                } else
                    decoder(parentNode.getRightChild(), string, i);
            }
        }
        return decoder.charAt(0);
    }

    // Returns the root node of the binary tree
    public static TreeNode<Character> getDecodingTree() {
        TreeNode<Character> root = makeTree();

        return root;
    }

    public static TreeNode<Character> makeTree() {
        DecodingTree decodeTree = new DecodingTree();
        final String filePath = "/data/morseCode.txt";
        final InputStream inputFile = MorseCode.class.getResourceAsStream(filePath);
        final Scanner input = new Scanner(inputFile);
        while (input.hasNextLine()) {
            String characterValue = input.next();
            Character character = characterValue.charAt(0);
            String code = input.next();
            decodeTree.insert(character, code);
        }
        input.close();

        TreeNode<Character> root = decodeTree.getRoot();
        return root;
    }
}
--------------------------------------------------------------------------------------------------------------------
import java.util.Stack;
public class DecodingTree {
    static class CharacterTreeNode implements TreeNode<Character> {
        private TreeNode<Character> leftChild;
        private TreeNode<Character> rightChild;
        private Character value;

        public CharacterTreeNode(Character i) {
            this.value = i;
        }

        @Override
        public TreeNode<Character> getLeftChild() {
            return this.leftChild;
        }

        @Override
        public TreeNode<Character> getRightChild() {
            return this.rightChild;
        }

        @Override
        public Character getValue() {
            return this.value;
        }

        public void setLeftChild(TreeNode<Character> newNode) {
            this.leftChild = newNode;
        }

        public void setRightChild(TreeNode<Character> newNode) {
            this.rightChild = newNode;
        }

    }

    private TreeNode<Character> root;

    public DecodingTree() {
        root = new CharacterTreeNode(null);
    }

    public TreeNode<Character> getRoot() {
        return this.root;
    }

    public void preorder(TreeNode<Character> root) {
        StringBuilder out = new StringBuilder();
        if (root == null)
            return;
        Stack<TreeNode<Character>> stack = new Stack<TreeNode<Character>>();
        stack.push(root);
        while (!stack.empty()) {
            TreeNode<Character> n = stack.pop();
            out.append(n.getValue());
            if (n.getLeftChild() != null) {
                stack.push(n.getLeftChild());
            }
            if (n.getRightChild() != null) {
                stack.push(n.getRightChild());
            }
        }
    }

    public void insert(Character character, String code) {

        CharacterTreeNode newNode = new CharacterTreeNode(character);
        int i = 1;
        if (root.getValue() == null) {
            root = new CharacterTreeNode('/');
        }
        if (root.getLeftChild() == null) {
            if ((code.charAt(i - 1) == '-') && (code.length() == i))
                ((CharacterTreeNode) root).setLeftChild(newNode);
        } else if (root.getRightChild() == null) {
            if ((code.charAt(i - 1) == '*') && (code.length() == i))
                ((CharacterTreeNode) root).setRightChild(newNode);
        } else if (code.length() > i) {
            if ((code.charAt(i - 1) == '-') && (root.getLeftChild() != null)) {
                insert(root.getLeftChild(), newNode, code, i);
            } else if ((code.charAt(i - 1) == '*') && (root.getRightChild() != null)) {
                insert(root.getRightChild(), newNode, code, i);
            }
        }
    }

    public void insert(TreeNode<Character> parentNode, CharacterTreeNode newNode, String code, int i) {
        i++;
        if (code.charAt(i - 1) == '-') {
            if (code.length() == i) {
                if (parentNode.getLeftChild() == null)
                    ((CharacterTreeNode) parentNode).setLeftChild(newNode);
            } else
                insert(parentNode.getLeftChild(), newNode, code, i);

        } else if (code.charAt(i - 1) == '*') {
            if (code.length() == i) {
                if (parentNode.getRightChild() == null)
                    ((CharacterTreeNode) parentNode).setRightChild(newNode);
            } else
                insert(parentNode.getRightChild(), newNode, code, i);
        }
    }
}
----------------------------------------------------------------------------------------------------------------
public interface TreeNode<T> {
    TreeNode<T> getLeftChild();
    TreeNode<T> getRightChild();
    T getValue();
}