---
# System prepended metadata

title: A simple Java CLI (part 2) - Solution

---

# A simple Java CLI (part 2) - Solution
Solution to the [Brief - A simple Java CLI (part 2)](https://hackmd.io/YZIFZiAEQF2DEikHgsskBw).

## What where the prerequisites?
You should be comfortable with topics below. If it not the case, you should learn more about:

- Have assimilated the previous concepts (part 1)
- Understand what folders and files are
- Understand what a path (to a folder or file) is

## What was expected
- Understand the specifications!
- Deliver no more or less than expected :)
- Rely on the solution of part 1
- Better tests before delivery (advice in part 1 solution)

## The code
This is not the unique possible implementation neither a fully optimized implementation, it is not the objective. It goes straight to the point which is satisfying the specifications.

**Challenge:**
But it introduces using a `StringBuilder` instead of string concatenation in the `printenv` command. Building strings can be a costly operation because a `String` object in Java is an array of characters and it is immutable (state cannot change once created); each time you concatenate strings, Java builds new `String` objects. When we need to build dynamically a string and typically in loops it is a far way better solution to use the `StringBuilder` class.

```java=
import java.io.File;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

public class Cli {

    public static void main(String[] args) {
	Scanner scanner = new Scanner(System.in);
	System.out.print("> ");
	while (true) {
	    String commandLine = scanner.nextLine();
	    String[] tokens = commandLine.split(" ", 2);
	    String commandName = tokens[0];
	    String output = "";
	    if (commandName.equals("exit") || commandName.equals("logout")) {
		break;
	    } else if (commandName.equals("date")) {
		output = LocalDate.now().toString();
	    } else if (commandName.equals("time")) {
		output = LocalTime.now().toString();
	    } else if (commandName.equals("datetime")) {
		output = LocalDateTime.now().toString();
	    } else if (commandName.equals("useraccount")) {
		output = System.getProperty("user.name");
	    } else if (commandName.equals("userhome")) {
		output = System.getProperty("user.home");
	    } else if (commandName.equals("os")) {
		String name = System.getProperty("os.name");
		String version = System.getProperty("os.version");
		output = name + " (" + version + ")";
	    } else if (commandName.equals("printenv")) {
		if (tokens.length == 2) { // Single variable
		    String name = tokens[1];
		    String value = System.getenv(name);
		    if (value != null) {
			output = value;
		    }
		} else { // All variables
		    Map<String, String> variables = System.getenv();
		    Set<String> keys = variables.keySet();
		    StringBuilder sb = new StringBuilder();
		    for (String key : keys) {
			sb.append(key);
			sb.append("=");
			sb.append(variables.get(key));
			sb.append(System.lineSeparator());
		    }
		    output = sb.toString();
		}
	    } else if (commandName.equals("ls")) {
		if (tokens.length == 2) { // We have a path candidate
		    String path = tokens[1];
		    File dir = new File(path);
		    String[] names = dir.list();
		    if (names != null) { // Denotes a directory
			for (String name : names) {
			    output += name + System.lineSeparator();
			}
		    } else {
			output = "Not a directory";
		    }
		} else {
		    output = "Not a directory";
		}
	    } else if (commandName.equals("echo") || commandName.equals("print")) {
		if (tokens.length == 2) {
		    output = tokens[1];
		}
	    } else {
		output = "Command '" + commandName + "' not found.";
	    }
	    System.out.println(output);
	    System.out.print("> ");
	}
	scanner.close();
	System.out.println("Bye!");
    }

}
```

## About Java core concepts in this brief
- Data structures: the basic `array`, `Map` (dictionary-like structure with keys and values) and `Set` (contains unique elements)
- `File` class to represent a file on disk and methods to get related information on the file such as its name
- Looping over data structures with the "foreach" enhanced `for` loop also called `foreach` loop
- Computers need to know when we have reached the end of a line, an "end-of-line separator" which is system dependent and that Java has an utility method to retrieve the system running our program specific separator