Skip to content

Commit

Permalink
Added some documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
3arthqu4ke committed Aug 23, 2024
1 parent b46e371 commit a65e677
Show file tree
Hide file tree
Showing 21 changed files with 194 additions and 29 deletions.
7 changes: 7 additions & 0 deletions buildSrc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# HeadlessMc-Modules

A gradle plugin allowing us to generate Java 9+ module-info classes. For an example take a look at the
headlessmc-lwjgl [build.gradle](../headlessmc-lwjgl/build.gradle), there we open all packages in order to allow the
transformed lwjgl classes to access the RedirectionApi (to do that we also need to transform lwjgls' module-info to open
the headlessmc.lwjgl module). I tried around with other gradle plugins which allow you to cross compile to Java 8 while
generating module-info classes but all caused problems in one way or the other.
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,52 @@
import me.earth.headlessmc.api.command.line.CommandLine;
import me.earth.headlessmc.api.config.HasConfig;
import me.earth.headlessmc.api.exit.ExitManager;
import me.earth.headlessmc.logging.Logger;
import me.earth.headlessmc.logging.LoggingService;

/**
* Represents a HeadlessMc instance.
* An instance handles commands, logging and configuration and exiting the process.
*/
public interface HeadlessMc extends LogsMessages, HasConfig {
/**
* Safe Wrapper for dev.xdark.deencapsulation.Deencapsulation,
* which can be used to access classes beyond Java 9 module boundaries.
*
* @return a service that can be used to access classes beyond Java 9 module boundaries.
*/
Deencapsulator getDeencapsulator();

/**
* Returns the command line belonging to this instance.
* The command line manages commands and the terminal for this HeadlessMc instance.
*
* @return the command line instance managing commands and the terminal for this HeadlessMc instance.
*/
CommandLine getCommandLine();

/**
* Instead of calling {@link System#exit(int)} it is advised to call this instead.
*
* @return the manager managing exiting this java process.
*/
ExitManager getExitManager();

/**
* The LoggingService for this instance.
* Configures {@link Logger}s.
*
* @return the logging service for this instance.
*/
LoggingService getLoggingService();

/**
* Logs the given message in a human-readable format instead of logging it.
* This method is meant to be used instead of a logger for communicating
* console output to the user.
*
* @param message the message to log on the console.
*/
@Override
default void log(String message) {
getCommandLine().getInAndOutProvider().getOut().get().println(message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
import me.earth.headlessmc.api.exit.ExitManager;
import me.earth.headlessmc.logging.LoggingService;

/**
* A default implementation for the {@link HeadlessMc} interface.
*/
@Getter
@RequiredArgsConstructor
public class HeadlessMcImpl implements HeadlessMc {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.Data;
import me.earth.headlessmc.api.command.Command;
import me.earth.headlessmc.api.command.CommandException;
import me.earth.headlessmc.api.command.line.CommandLine;
import me.earth.headlessmc.api.util.ReflectionUtil;
import org.jetbrains.annotations.Nullable;

Expand All @@ -12,10 +13,20 @@
import java.util.Map;

/**
* A {@link Command} implementation that delegates to another command.
* This delegation happens via reflection so any object that exposes the same methods as {@link Command} can be used.
* This is generally meant for environments where the Command class has been loaded multiple times from multiple ClassLoaders.
* Through the Reflection delegation this allows you to communicate commands between ClassLoaders.
*
* @see ApiClassloadingHelper
*/
@Data
public class ClAgnosticCommand implements Command {
/**
* A remote instance of {@link Command}, potentially loaded by another classloader.
* Because of that we cannot cast it to a Command directly,
* but need to use reflection to access its methods.
*/
private final Object delegate;

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@
import java.util.Map;

/**
* A {@link CommandContext} implementation that delegates to another CommandContext.
* This delegation happens via reflection so any object that exposes the same methods as {@link CommandContext} can be used.
* This is generally meant for environments where the CommandContext class has been loaded multiple times from multiple ClassLoaders.
* Through the Reflection delegation this allows you to communicate commands between ClassLoaders.
*
* @see ApiClassloadingHelper
*/
@Data
public class ClAgnosticCommandContext implements CommandContext {
/**
* A remote instance of {@link CommandLine}, loaded by another classloader.
* A remote instance of {@link CommandLine}, potentially loaded by another classloader.
* Because of that we cannot cast it to a CommandContext directly,
* but need to use reflection to access its methods.
* This CommandContext delegates to the commandContext provided by this command line.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import java.util.LinkedHashMap;
import java.util.Map;

/**
* Abstract base class for {@link Command}.
*/
@EqualsAndHashCode
@RequiredArgsConstructor
public abstract class AbstractCommand implements Command {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* Commands are managed by a {@link CommandContext}.
* Due to classloading problems, Commands and CommandContext both only expose methods
* where parameters and return values are from the java packages (see {@link ApiClassloadingHelper}).
*
* @see AbstractCommand
*/
public interface Command extends HasName, HasDescription, HasArguments {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,25 @@
import lombok.RequiredArgsConstructor;
import lombok.val;
import me.earth.headlessmc.api.HeadlessMc;
import me.earth.headlessmc.api.LogsMessages;
import me.earth.headlessmc.api.config.HmcProperties;
import org.jetbrains.annotations.NotNull;

import java.util.*;

/**
* Default implementation of {@link CommandContext}.
*/
@RequiredArgsConstructor
@SuppressWarnings({"unchecked", "RedundantSuppression"}) // delegate
public class CommandContextImpl implements CommandContext {
/**
* The list of Commands that this CommandContext can execute.
*/
protected final List<Command> commands = new ArrayList<>();
/**
* The HeadlessMc instance this CommandContext uses for {@link LogsMessages#log(String)}.
*/
protected final HeadlessMc log;

@Override
Expand All @@ -31,6 +41,14 @@ public void execute(String message) {
}
}

/**
* Calls {@link Command#execute(String, String...)} on the given command for the given Arguments.
* Catches any {@link CommandException} that might occur and logs it.
*
* @param cmd the command to execute.
* @param message the full command.
* @param args the message split into arguments.
*/
protected void executeCommand(Command cmd, String message, String... args) {
try {
cmd.execute(message, args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
*/
@StandardException
public class CommandException extends Exception {
/**
* Constructs a new CommandException with the specified detail message. The
* cause is not initialized, and may subsequently be initialized by
* a call to {@link #initCause}.
*
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public CommandException(String message) {
super(message);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,23 @@

import me.earth.headlessmc.api.HasName;
import me.earth.headlessmc.api.HeadlessMc;
import me.earth.headlessmc.api.command.AbstractCommand;
import me.earth.headlessmc.api.command.Command;
import me.earth.headlessmc.api.command.CommandException;
import me.earth.headlessmc.api.command.HasDescription;
import me.earth.headlessmc.api.command.*;
import me.earth.headlessmc.api.command.line.CommandLine;
import me.earth.headlessmc.api.util.Table;

import java.util.Map;

/**
* A {@link Command} implementation that displays information about Commands from a {@link CommandContext}.
*/
public class HelpCommand extends AbstractCommand {
/**
* Constructs a new HelpCommand.
* The {@link CommandContext} from the {@link CommandLine} of the given {@link HeadlessMc}
* will be used to list commands and to find commands to display information for.
*
* @param ctx the HeadlessMc instance holding the CommandLine with the commands.
*/
public HelpCommand(HeadlessMc ctx) {
super(ctx, "help", "Information about commands.");
args.put("<command>", "The name of the command to get help for.");
Expand All @@ -25,25 +33,22 @@ public void execute(String line, String... args) throws CommandException {
if (args.length > 2) {
String desc = cmd.getArgDescription(args[2]);
if (desc == null) {
throw new CommandException(
"No description found for '" + args[2] + "'.");
throw new CommandException("No description found for '" + args[2] + "'.");
} else {
ctx.log(String.format(
"%s %s: %s", cmd.getName(), args[2], desc));
ctx.log(String.format("%s %s: %s", cmd.getName(), args[2], desc));
}
} else {
ctx.log(String.format("%s : %s", cmd.getName(),
cmd.getDescription()));
ctx.log(String.format("%s : %s", cmd.getName(), cmd.getDescription()));
ctx.log(
new Table<Map.Entry<String, String>>()
.withColumn("arg", Map.Entry::getKey)
.withColumn("description", Map.Entry::getValue)
.addAll(cmd.getArgs2Descriptions())
.build());
.build()
);
}
} else {
throw new CommandException(
String.format("Couldn't find command %s", args[1]));
throw new CommandException(String.format("Couldn't find command %s", args[1]));
}
} else {
ctx.log(
Expand All @@ -52,7 +57,8 @@ public void execute(String line, String... args) throws CommandException {
.withColumn("description", HasDescription::getDescription)
.withColumn("args", this::argsToString)
.addAll(ctx.getCommandLine().getCommandContext())
.build());
.build()
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,29 @@

import lombok.val;
import me.earth.headlessmc.api.HeadlessMc;
import me.earth.headlessmc.api.LogsMessages;
import me.earth.headlessmc.api.command.AbstractCommand;
import me.earth.headlessmc.api.command.Command;
import me.earth.headlessmc.api.command.CommandException;

import java.math.RoundingMode;
import java.text.DecimalFormat;

/**
* A {@link Command} implementation that displays the currently used memory, free memory and max memory of the JVM.
*/
public class MemoryCommand extends AbstractCommand {
private static final DecimalFormat DF = new DecimalFormat("#.##");

static {
DF.setRoundingMode(RoundingMode.CEILING);
}

/**
* Constructs a new MemoryCommand instance.
*
* @param ctx the {@link LogsMessages} used to log the output.
*/
public MemoryCommand(HeadlessMc ctx) {
super(ctx, "memory", "Displays Memory stats.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,24 @@

import me.earth.headlessmc.api.HeadlessMc;
import me.earth.headlessmc.api.command.AbstractCommand;
import me.earth.headlessmc.api.command.Command;
import me.earth.headlessmc.api.command.CommandException;
import me.earth.headlessmc.api.command.QuickExitCli;
import me.earth.headlessmc.api.command.line.CommandLine;

/**
* A {@link Command} that treats its given arguments as commands and executes them.
* This is useful when you want to start HeadlessMc with the {@link QuickExitCli}
* from the command line; and you want to execute multiple commands that you know beforehand.
*/
public class MultiCommand extends AbstractCommand {
/**
* Constructs a new MultiCommand command.
* The {@link CommandLine} of the given {@link HeadlessMc} instance
* will be used to execute the given commands.
*
* @param ctx the HeadlessMc instance supplying the {@link CommandLine} to execute commands on.
*/
public MultiCommand(HeadlessMc ctx) {
super(ctx, "multi", "Run multiple commands together.");
args.put("<command1 command2...>", "The commands to run.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@

import me.earth.headlessmc.api.HeadlessMc;
import me.earth.headlessmc.api.command.AbstractCommand;
import me.earth.headlessmc.api.command.Command;
import me.earth.headlessmc.api.exit.ExitManager;

import java.util.Locale;

/**
* A {@link Command} that calls HeadlessMc's {@link ExitManager} to quit the process.
*/
public class QuitCommand extends AbstractCommand {
/**
* Constructs a new QuitCommand.
*
* @param ctx the HeadlessMc instance to get the {@link ExitManager} from.
*/
public QuitCommand(HeadlessMc ctx) {
super(ctx, "quit", "Quits HeadlessMc.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@

import lombok.CustomLog;
import me.earth.headlessmc.api.HeadlessMc;
import me.earth.headlessmc.api.process.InAndOutProvider;

import java.io.BufferedReader;
import java.io.IOError;
import java.io.IOException;
import java.io.InputStreamReader;

/**
* The simplest {@link CommandLineReader} implementation,
* which reads {@link InAndOutProvider#getIn()} with a {@link BufferedReader}.
*/
@CustomLog
public class BufferedCommandLineReader implements CommandLineReader {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
import lombok.CustomLog;
import lombok.RequiredArgsConstructor;
import me.earth.headlessmc.api.HeadlessMc;
import me.earth.headlessmc.api.process.InAndOutProvider;

import java.io.Console;
import java.io.IOError;

/**
* An implementation of {@link CommandLineReader} that reads from the console supplied by {@link InAndOutProvider#getConsole()}.
* This is usually {@link System#console()}.
*/
@CustomLog
@RequiredArgsConstructor
class ConsoleCommandLineReader implements CommandLineReader {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
import java.io.Console;
import java.util.function.Supplier;

/**
* A {@link CommandLineReader} that decides whether to use a {@link BufferedCommandLineReader} or a {@link ConsoleCommandLineReader}.
* If the {@link InAndOutProvider#getConsole()} is available a {@link ConsoleCommandLineReader} will be used always.
*
* @see BufferedCommandLineReader
* @see ConsoleCommandLineReader
*/
@CustomLog
@RequiredArgsConstructor
public class DefaultCommandLineProvider implements Supplier<CommandLineReader> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import lombok.Setter;
import me.earth.headlessmc.api.command.PasswordAware;

/**
* Simplest implementation of {@link PasswordAware}.
*/
@Getter
@Setter
public class PasswordAwareImpl implements PasswordAware {
Expand Down
Loading

0 comments on commit a65e677

Please sign in to comment.