Changes

Created page with "see <code>Actions.java</code>, <code>Action.java</code>, <code>ClientInstall/ServerInstall/ExtractAction.java</code> example with <code>ExtractAction</code>: <code>final Acti..."
see <code>Actions.java</code>, <code>Action.java</code>, <code>ClientInstall/ServerInstall/ExtractAction.java</code>

example with <code>ExtractAction</code>:
<code>final Actions action = Actions.EXTRACT;</code>

<code>action.getAction(installProfile, monitor)</code> will refer to the <code>BiFunction<Install, ProgressCallback, Action></code> action
inside the <code>Actions.java</code> enum which <code>Actions.EXTRACT</code> specifically populates as a new instance of
<code>ExtractAction.java</code> as the <code>BiFunction</code> (a <code>BiFunction</code> being an <code>Object</code> that takes two inputs, can do some work and has one output).

The <code>Install installProfile</code> and <code>ProgressCallback monitor</code> arguments are then applied to the <code>BiFunction</code>,
which causes <code>ExtractAction</code>'s constructor to be called with those arguments.

<code>ExtractAction</code>'s constructor calls its parent constructor (Action.java) with <code>super(profile, monitor, true)</code>.
true being <code>isClient</code> here.

<code>Action.java</code>'s constructor populates some variables and instantiates <code>PostProcessors.java</code>, which calls
the <code>installProfile</code>'s <code>getProcessors("client")</code> and <code>getData(true)</code> methods and stores their results in a
<code>List<Processor></code> and a <code>Map<String, String></code>, respectively. <code>Install#getProcessors()</code> will return an empty list
and <code>Install#getData()</code> will return a new, empty <code>HashMap</code>, this is just to set things up for when the action
is ran.

<code>action.getAction(installProfile, monitor).run(target, a -> true)</code>

The <code>ExtractAction.java</code> overrides the <code>run(File, Predicate<String>)</code> method. In this case, the args from the
run method invocation above provide the target directory to extract to and what's basically an unused
truthy boolean value.

This run method returns true if successful and false otherwise. It gets the <code>path</code> variable from the parsed
<code>installProfile</code>, which is the Maven artifact path for the 'main' jar and is an instance of <code>Artifact.java</code>.

<code>Artifact.java</code> uses an <code>Adapter</code> subclass that implements a JSON deserializer and serializer that gets the
JSON primitive String and calls the Artifact#from(String) to split the maven descriptor into its parts and
build a path to it inside the Installer jar.

It then calls DownloadUtils#extractFile(Artifact, File, String) with the Maven artifact path to extract from,
the target path to put it in when extracted and a <code>null</code> (meaning don't verify its checksum after extracting it).

Extracting the <code>Artifact</code> is easier than it sounds, it just grabs a file embedded within the jar under the
maven folder (similar to how the install_profile.json is obtained) and copies it to the target path,
overwriting any existing files there and creating directories to put them in when necessary.

<code>if (action.getAction(installProfile, monitor).run(target, a -> true)) {</code>