Skip to content

General utility classes, including a generalized deterministic finite state machine (FSM), a non-interactive test framework, and much more...

Notifications You must be signed in to change notification settings

SlightlyLoony/Util

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Utilities Package

Java Utilities

A collection of Java utilities.

What are these utilities, anyway?

It’s very hard to give a general description of these, as there are a wide variety of them. The easiest thing to do is to browse the classes. There are a few worth mentioning here, however:

Table 1. Notable Elements

Name

Description

Non-Interactive Test Framework

A test framework that allows test code to be included in production builds, while enabling and parameterization is handled via a configuration file. This framework is intended primarily for use in embedded software and in server daemons, which share the characteristic of being non-interactive. Look in the test package for details. Much more in the Non-Interactive Test document

Java Configuration

Provides a simple, flexible mechanism to write configuration files in Java. Much more in the Java Configuration document.

Command Line Argument Interpreter

Provides everything needed for a Java command line application (or server daemon) to have Unix-style arguments. Optional arguments can have any number of long and short names. Passwords (and other arguments) can be entered interactively. Parses and validates argument parameters. Provides summary and detailed help. Much more in the Command Line document.

Finite State Machine

Provides everything you need to build a finite state machine (FSM). While FSMs can be very complex, they can also be quite simple - and this FSM can provide the whole range. A simple FSM can be built in a single class, as you can see with the example FSM included in the package. This FSM package can also provide the guts of a very complex FSM, even those with nested FSMs. Much more in the FSM document.

Console

Allows you to connect from a client computer (such as your development laptop) to a "console server" embedded into an embedded system or daemon process. It’s the same idea as connecting with SSH, except that instead of connecting to the operating system shell (as SSH does), you’re connecting into an environment that you provide, embedded right into your application. The connection is encrypted, and mutual possession of the encryption key is the authentication. The author needed a way that he could communicate directly with a daemon process, over the network. This package is the generalized result of that need. Much more in the Console document.

Info

A family of classes that let do some very nice things with information that you want to publish from one source class, but make available read-only to multiple destinations classes. At the base of the family is the Info class, which is a generic class that simply contains a piece of immutable timestamped information (which can be an instance of any class). You can find all the info classes here, and a very simple example program that illustrates the uses of the info package here.

Haps

A single generic class that implements a lightweight, performant event system (a "Hap" is short for a "Happening", or an event). The generic type for the Haps<T> class is an enum that you define, with one value for every Hap that you need. Any Hap may optionally include an Object of any type that is the data associated with the Hap.

Some particular mentions…​

Outcomes

The Outcome class is a simple generic record with lots of potential. It’s intended to be used as a return value for functions implementing operations that might either success or fail (ok or not ok).

When the outcome is success (ok), the Outcome instance contains an ok flag set to true, and an optional info field that is the generic type of the Outcome. This info field is intended to contain any result of the operation other than success or failure.

When the outcome is failure (not ok), the Outcome instance contains an ok flag set to false, a mandatory explanatory message (as a string), and an optional Throwable that might provide even more information about the failure.

String substitutions

The string substitutions provide a simple way to replace keys in a target string with other values. Generally the substitution key/value pairs are stored in a text file, but that’s not a requirement. The substitutions are implemented in Strings.substitute().

The key/value pairs must be formatted according to the following rules:

  • A key starts at the beginning of the file or string, or after a newline.

  • A key can be a string containing any characters other than a colon (":"). A colon terminates the key. Generally the key should be some string that is impossible (or extremely unlikely) to appear in the actual text. For example, <{<{password}>}> might be a good key.

  • Whitespace (including newlines) after a key termination colon are ignored.

  • The value may appear on the same line as the key. In this case, the value is terminated by the next newline or the end of the file. For instance, <{<{password}>}>: oh,my,gobbledegook822 is a key/value pair with the key <{<{password}>}> and the value oh,my,gobbledegook822.

  • The value may appear on lines following the key, which is especially useful when the value must have newlines in it. The value on the first line following the key is the delimiter, which is then followed by the lines of the value, which is then followed by the delimiter, repeated. See the example below to get an idea how this works.

  • A newline-terminated value may contain any characters other than a newline.

  • A multiline value may contain anything other than the delimiter string - but this is not really a limitation, as the delimiter string is under the user’s control. If the terminating delimiter appears on a line by itself, the value will have a trailing newline. If the terminating delimiter appears at the end of the last line of the value, the value will not have a trailing newline.

  • Substitutions are performed in the order that they appear in the substitutions document.

  • Substitutions are not recursive - if a value contains a key, that key will not be replaced by it’s value.

  • If the same key appears in the substitutions document multiple times, it will be processed each time, on the text that is the result of all the prior substitutions. This is not quite recursion, although it may have a similar effect. Note that there is no requirement that the value be the same for each occurrence of the key.

<{<{password}>}>: oh,my,gobbledegook822
***yikes***:
DELIMITER
This is a really big value.
It appears on multiple lines.
With this, one can control the world.
Well, a little world.
DELIMITER

LogFormatter

This is a formatter for the java.util.logging file or console logging, providing a format to the author’s liking. Of note, it supports logging thread names (instead of the standard thread IDs), and it supports logging stack traces for exceptions being logged. It has some properties which modify its behavior:

Table 2. LogFormatter properties

Property

Description

com.dilatush.util.LogFormatter.messageWidth

You’ll be stunned to know that this property will set the message column width to something other than its default (60).

com.dilatush.util.LogFormatter.sourceWidth

Just as amazing is this versatile property, which will set the source class column width to something other than its default (30).

com.dilatush.util.LogFormatter.threadIDWidth

Last, but certainly not least, is this vital property, which will set the thread ID column width to something other than its default (30).

Why does the world need these utilities?

Well, probably the world doesn’t actually need ShedSolar – it’s mainly here for the author’s personal use and enjoyment, but with some faint hope that someone else with the same challenges the author faced will also find it useful.

Dependencies and Java Version

This package has one dependency: The excellent, bog-standard Java JSON module, freely available from https://github.com/stleary/JSON-java.

This package must be compiled with Java version 15 (with preview code enabled) or later.

Why is this package’s code so awful?

The author is a retired software and hardware engineer who did this just for fun, and who (so far, anyway) has no code reviewers to upbraid him. Please feel free to fill in this gap! You may contact the author at [email protected].

Some implementation notes…​

If you dig into this package in detail, you may notice that the source code in some areas has a different style from that in other areas. This is simply because it was written over a period of over ten years, and the author’s coding style has evolved over that time.

How is this package licensed?

Util is licensed with the quite permissive MIT license:

Created: January 19, 2021
Author: Tom Dilatush <[email protected]>
Github:  https://github.com/SlightlyLoony/Util
License: MIT

Copyright 2020 Tom Dilatush (aka "SlightlyLoony")

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so.

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About

General utility classes, including a generalized deterministic finite state machine (FSM), a non-interactive test framework, and much more...

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published