Getting the Gist of Java
Tags: java, regex, shell, maven
Published: 2018-11-12 16:52:19

### or
# I Had A Very Busy Weekend

To catch up on a backlog of work for an upcoming deadline, I spent most of this past weekend coding (writing new stuff and fixing up old projects). Check out some of these Gists I wrote and gimme those sweet, sweet stars:

1. [PNode](https://gist.github.com/awwsmm/16d2357c8e929c327c5e2f57aa08b416) - yet another tree structure for Java
2. [Typifier](https://gist.github.com/awwsmm/56b8164410c89c719ebfca7b3d85870b) - parse the `String` representation of an object into one of Java's primitive wrapper classes (also `LocalDateTime` for timestamps)
3. [ExpandPath](https://gist.github.com/awwsmm/7d947dc26688227225a6942467e6e1e5) - interprets `~` or `~user` home directories, `%ENVIRONMENT%` `$VARIABLES`, and gl`*`bs to return lists of files, on both Windows and Linux.
4. [SplitXSV](https://gist.github.com/awwsmm/3527b995f25f74268b02e330fd4311ba) - splits a line of sentinel-separated text and returns the result
5. [Maven-With-Resources](https://github.com/awwsmm/Maven-With-Resources) - a small example repo to show how to read `src/main/resources/` files within the code of a Maven project
6. [ParseFileName](https://gist.github.com/awwsmm/002c099e68265b8a171980a4038adb6e) - parse a file name and return the path, filename itself, and extension (if it exists) in a `String[]`.
7. [ParseCLArgs](https://gist.github.com/awwsmm/01e8d63c24690582fa4cf0d008a93f38) - parse command-line arguments and categorize as standard arguments or flags

See short descriptions and examples of these projects below:

---

## [PNode](https://gist.github.com/awwsmm/16d2357c8e929c327c5e2f57aa08b416)

There is no [shortage](https://www.baeldung.com/java-binary-tree) of [custom-made](https://github.com/gt4dev/yet-another-tree-structure) [tree structures](http://vivin.net/2010/03/02/maven-project-for-generic-n-ary-tree-in-java/) written in Java, probably because the best implementation only exists in the [javax.swing](https://docs.oracle.com/javase/6/docs/api/javax/swing/tree/package-summary.html) package, which is now [de facto deprecated](https://www.quora.com/Is-it-worth-learning-Swing-in-2017), replaced by JavaFX. So I wrote a tree (or rather a node) class where each node has a label and a value (both or either of which can be `null`). The nodes are kept track of via their indices in `List`s, which means when a node is "deleted", it's replaced by a `null` to maintain `List` indexing.

```
Original tree:

    0 |-- n01_label
    1 |    |-- n02_label
    2 |    |    |-- n04_label
    2 |    |    |-- n05_label
    3 |    |         |-- n08_label
    1 |    |-- n03_label
    2 |         |-- n06_label
    2 |         |-- n07_label


Tree after orphaning n05:

    0 |-- n01_label
    1 |    |-- n02_label
    2 |    |    |-- n04_label
    1 |    |-- n03_label
    2 |         |-- n06_label
    2 |         |-- n07_label


n05 tree after orphaning n05:

    0 |-- n05_label
    1 |    |-- n08_label


Tree after adopting n05:

    0 |-- n01_label
    1 |    |-- n02_label
    2 |    |    |-- n04_label
    1 |    |-- n03_label
    2 |    |    |-- n06_label
    2 |    |    |-- n07_label
    1 |    |-- n05_label
    2 |         |-- n08_label

```
---

## [Typifier](https://gist.github.com/awwsmm/56b8164410c89c719ebfca7b3d85870b)

Often, when parsing text files, you want to determine the type of data represented by the `String`s you're reading in. `Typifier` allows interpretation of `String` data as any of Java's primitive wrapper types, boxing data in the narrowest type possible. The code also allows for the user to define timestamp formats so that `String`s can be parsed as `LocalDateTime` objects as well! To speed up processing of large data sets, interpretation can be restricted to "common" types only (`Double`, `Boolean`, `LocalDateTime`, `String`).

```
String.trim() is used to remove leading and trailing whitespace, so the following work fine:

  typify (" 23 ") => "23" [Byte]
  typify ("     3.4 ") => "3.4" [Float]

But if the user enters only whitespace, that's fine, too:

  typify (" ") => " " [String]
  typify ("    ") => "    " [String]

The user can choose to interpret 1/0 as true/false:

  typify ("1") => "true" [Boolean]
  typify ("true") => "true" [Boolean]
  typify ("0") => "false" [Boolean]

Ranges of Byte, Short, and Float are used to box the value in the narrowest type available:

  typify (" 2 ") => "2" [Byte]
  typify (" 200 ") => "200" [Short]
  typify ("2e9 ") => "2.0E9" [Float]
  typify (" 2e99") => "2.0E99" [Double]

If String has length 1 and is not Boolean or Byte, it will be assigned the Character type:

  typify ("4") => "4" [Byte]
  typify ("-") => "-" [Character]
  typify ("a") => "a" [Character]

Dates can also be parsed, and formats can be defined by the user:

  typify ("2014-12-22 14:35:22") => "2014-12-22 14:35:22" [LocalDateTime]
  typify ("3/5/99 6:30") => "3/5/99 6:30" [LocalDateTime]

```
---

## [ExpandPath](https://gist.github.com/awwsmm/7d947dc26688227225a6942467e6e1e5)

Passing lists of files via the command line to a Java program doesn't always work as expected. The shell can auto-expand `$ENVIRONMENT_VARIABLES` or gl`*`bs, and lots of features available in `bash` aren't available in the Windows `cmd.exe` prompt. This script allows for paths to be interpreted the same way on Windows and Unix and adds recursive "double-globbing" (`**`) to pre-bash4 shells (as well as `cmd`), among other cool features.

```
C:\>java ExpandPath "~/test/**.txt"

arg: '~/test/**.txt'

  C:\Users\andrew.watson\test\a\d\a.txt
  C:\Users\andrew.watson\test\b\d\e.txt
  C:\Users\andrew.watson\test\a\d\d.txt
  C:\Users\andrew.watson\test\a.txt
  C:\Users\andrew.watson\test\c\c.txt
  C:\Users\andrew.watson\test\1.txt
  C:\Users\andrew.watson\test\b\d\a.txt
  C:\Users\andrew.watson\test\b\b.txt
  C:\Users\andrew.watson\test\b\d\f.txt
  C:\Users\andrew.watson\test\0.txt
  C:\Users\andrew.watson\test\a\a.txt
  C:\Users\andrew.watson\test\b\a.txt
```
---

## [SplitXSV](https://gist.github.com/awwsmm/3527b995f25f74268b02e330fd4311ba)

This script splits a line of sentinel-separated text and returns the resulting tokens. Any non-alphanumeric character is preceded with a `'\'` to escape it, so even tabs or line breaks can be used as the delimiters.

```
given sentinel: '-'

given string:
{1-800-944-2345}

result:
{1}, {800}, {944}, {2345}

----------

given sentinel: ' '

given string:
{hi how are you}

result:
{hi}, {how}, {are}, {you}

```
---

## [Maven-With-Resources](https://github.com/awwsmm/Maven-With-Resources)

It can be frustrating to try to figure out how to read "resource" files in the code of a Maven project. There are differing and contradictory answers online. For posterity, I've set up a MWE Maven Project that shows how to read files located at `src/main/resources` and use those files in your Java code.

{% github awwsmm/Maven-With-Resources %}

---

## [ParseFileName](https://gist.github.com/awwsmm/002c099e68265b8a171980a4038adb6e)

This short script is useful for quickly getting the containing directory of a file or its extension. The user can them selectively process files based on those attributes.

```
The lines:

    System.out.println(Arrays.toString(parseFileName("test").get()));
    System.out.println(Arrays.toString(parseFileName("test.a").get()));
    System.out.println(Arrays.toString(parseFileName("test.a.b").get()));

...yield the output:

[/home/andrew, test, ]
[/home/andrew, test, a]
[/home/andrew, test, a.b]
```
---

## [ParseCLArgs](https://gist.github.com/awwsmm/01e8d63c24690582fa4cf0d008a93f38)

This is another short script that parses command-line arguments as basic `ARGUMENT`s, `FLAG`s (like `-this`), `LONGFLAG`s (like `--this`), or `OTHER` (only `-` or `--`). The arguments are returned in-order in a `List` so the user can determine whether or not the provided flags and arguments are valid.

```
$ java ParseCLArgs arg -short anotherArg --long - -- ---toolong
ARGUMENT=arg
FLAG=short
ARGUMENT=anotherArg
LONGFLAG=long
OTHER=-
OTHER=--
LONGFLAG=-toolong
```
---

So there you have it! That's how much coding you can get done in one weekend if you do nothing else but eat and sleep. 0/10 would not recommend.