Perform code maintenance

Please note that this commit may not fully compile as I'm currently working on a rendering subsystem rewrite.
This commit is contained in:
JeremyStar™ 2024-11-24 13:28:15 +01:00
parent 8bd0896415
commit 64f48a472f
Signed by: JeremyStarTM
GPG key ID: E366BAEF67E4704D
51 changed files with 717 additions and 1653 deletions

View file

@ -72,6 +72,8 @@ To change them, simply append `-P<property>` or `-P<property>=<value>`, like thi
#### Parallelism
Use the `jobs` property to control how many jobs will get executed simultaneously.
On Linux, specify `-Pjobs=$(nproc)`. Defaults to `8`.
#### Rendering
You can use the `renderingPlatform` property to control which rendering platform to initialize for.
#### JVM Home
You can use the `graalHome` property to specify the `$JAVA_HOME` of your local GraalVM installation.
Only used in the `nativeImage` task. Useful if you aren't using GraalVM as your primary JDK.

View file

@ -35,10 +35,9 @@ import de.staropensource.engine.base.logging.backend.async.LoggingQueue;
import de.staropensource.engine.base.logging.backend.async.LoggingThread;
import de.staropensource.engine.base.type.DependencyVector;
import de.staropensource.engine.base.type.EngineState;
import de.staropensource.engine.base.type.immutable.ImmutableLinkedList;
import de.staropensource.engine.base.utility.DependencyResolver;
import de.staropensource.engine.base.utility.FileAccess;
import de.staropensource.engine.base.utility.Miscellaneous;
import de.staropensource.engine.base.utility.misc.Miscellaneous;
import de.staropensource.engine.base.utility.PlaceholderEngine;
import de.staropensource.engine.base.utility.information.EngineInformation;
import de.staropensource.engine.base.utility.information.JvmInformation;
@ -114,7 +113,7 @@ public final class Engine extends SubsystemClass {
* @since v1-alpha1
*/
@Getter
private @NotNull ImmutableLinkedList<@NotNull DependencySubsystemVector> subsystems = new ImmutableLinkedList<>();
private @NotNull List<@NotNull DependencySubsystemVector> subsystems = Collections.emptyList();
/**
* Contains the engine's shutdown handler.
@ -291,8 +290,8 @@ public final class Engine extends SubsystemClass {
new Engine();
} catch (RuntimeException exception) {
Logger.error("Engine initialization failed");
Logger.error(Miscellaneous.getStackTraceHeader(exception.getCause()));
for (String line : Miscellaneous.getStackTraceAsString(exception.getCause(), true).split("\n"))
Logger.error(Miscellaneous.getThrowableHeader(exception.getCause()));
for (String line : Miscellaneous.stackTraceAsString(exception.getCause(), true).split("\n"))
Logger.error(line);
throw new RuntimeException("Engine initialization failed", exception.getCause());
@ -366,7 +365,6 @@ public final class Engine extends SubsystemClass {
EventHelper.cacheEvent(EngineSoftCrashEvent.class);
EventHelper.cacheEvent(InternalEngineShutdownEvent.class);
EventHelper.cacheEvent(LogEvent.class);
EventHelper.cacheEvent(ThrowableCatchEvent.class);
}
/**
@ -401,7 +399,7 @@ public final class Engine extends SubsystemClass {
}
// Update 'subsystems'
subsystems = new ImmutableLinkedList<>(subsystemsMutable);
subsystems = Collections.unmodifiableList(subsystemsMutable);
}
/**
@ -488,7 +486,7 @@ public final class Engine extends SubsystemClass {
}
// Update 'subsystems'
subsystems = new ImmutableLinkedList<>(order);
subsystems = Collections.unmodifiableList(order);
}
/**

View file

@ -20,11 +20,11 @@
package de.staropensource.engine.base;
import de.staropensource.engine.base.exception.IllegalAccessException;
import de.staropensource.engine.base.implementable.Event;
import de.staropensource.engine.base.implementable.EventListenerCode;
import de.staropensource.engine.base.implementable.ShutdownHandler;
import de.staropensource.engine.base.implementable.helper.EventHelper;
import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.type.EventPriority;
import de.staropensource.engine.base.type.InternalAccessArea;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
@ -77,7 +77,7 @@ public final class EngineInternals {
* use case and application.
*
* @see EventHelper#registerEvent(Class, EventListenerCode)
* @see EventHelper#registerEvent(Class, EventListenerCode, EventPriority)
* @see EventHelper#registerEvent(Class, EventListenerCode, Event.Priority)
* @since v1-alpha5
*/
private boolean reflectiveClasspathScanning = true;
@ -191,7 +191,7 @@ public final class EngineInternals {
* @return reflective classpath scanning flag state
* @throws IllegalAccessException when restricted ({@link InternalAccessArea#REFLECTIVE_CLASSPATH_SCANNING_GET})
* @see EventHelper#registerEvent(Class, EventListenerCode)
* @see EventHelper#registerEvent(Class, EventListenerCode, EventPriority)
* @see EventHelper#registerEvent(Class, EventListenerCode, Event.Priority)
* @since v1-alpha5
*/
public boolean getReflectiveClasspathScanning() throws IllegalAccessException {
@ -216,7 +216,7 @@ public final class EngineInternals {
* @param reflectiveClasspathScanning new reflective classpath scanning
* @throws IllegalAccessException when restricted ({@link InternalAccessArea#REFLECTIVE_CLASSPATH_SCANNING_OVERRIDE})
* @see EventHelper#registerEvent(Class, EventListenerCode)
* @see EventHelper#registerEvent(Class, EventListenerCode, EventPriority)
* @see EventHelper#registerEvent(Class, EventListenerCode, Event.Priority)
* @since v1-alpha5
*/
public void overrideReflectiveClasspathScanning(boolean reflectiveClasspathScanning) throws IllegalAccessException {

View file

@ -20,7 +20,6 @@
package de.staropensource.engine.base.annotation;
import de.staropensource.engine.base.implementable.Event;
import de.staropensource.engine.base.type.EventPriority;
import org.jetbrains.annotations.NotNull;
import java.lang.annotation.*;
@ -48,8 +47,8 @@ public @interface EventListener {
* Specifies the priority of the event.
*
* @return event priority
* @see EventPriority
* @see Event.Priority
* @since v1-alpha0
*/
@NotNull EventPriority priority() default EventPriority.DEFAULT;
@NotNull Event.Priority priority() default Event.Priority.DEFAULT;
}

View file

@ -1,61 +0,0 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Authors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.event;
import de.staropensource.engine.base.implementable.Event;
import de.staropensource.engine.base.implementable.helper.EventHelper;
import de.staropensource.engine.base.utility.Miscellaneous;
import org.jetbrains.annotations.NotNull;
/**
* Called when an exception is caught by {@link Miscellaneous#executeSafely(Runnable, String)}.
*
* @see Miscellaneous#executeSafely(Runnable, String)
* @since v1-alpha0
*/
public final class ThrowableCatchEvent implements Event {
/**
* Creates and initializes an instance of this event.
*
* @since v1-alpha0
*/
public ThrowableCatchEvent() {}
/**
* {@inheritDoc}
*
* @deprecated use the {@code callEvent} method with arguments
* @see ThrowableCatchEvent#callEvent(Throwable, String)
*/
@Deprecated
@Override
public void callEvent() {}
/**
* Emits the event and calls all event listeners.
*
* @param throwable caught throwable
* @param identifier an identifier given to the runnable
* @since v1-alpha0
*/
public void callEvent(@NotNull Throwable throwable, @NotNull String identifier) {
EventHelper.invokeAnnotatedMethods(getClass(), throwable, identifier);
}
}

View file

@ -20,7 +20,7 @@
package de.staropensource.engine.base.exception.reflection;
import de.staropensource.engine.base.type.reflection.ClassType;
import de.staropensource.engine.base.utility.ListFormatter;
import de.staropensource.engine.base.utility.misc.ListFormatter;
import org.jetbrains.annotations.NotNull;
/**

View file

@ -19,6 +19,7 @@
package de.staropensource.engine.base.implementable;
import de.staropensource.engine.base.annotation.EventListener;
import de.staropensource.engine.base.implementable.helper.EventHelper;
/**
@ -34,4 +35,76 @@ public interface Event {
* @since v1-alpha0
*/
void callEvent();
/**
* Specifies in which order {@link EventListener}s shall be called.
*
* @since v1-alpha9
*/
@SuppressWarnings({ "unused" })
enum Priority {
/**
* {@link EventListener}s with this
* priority are called before all others.
* <p>
* This priority is exclusive to the
* engine and subsystems and should
* not be used by applications.
*
* @since v1-alpha9
*/
EXCLUSIVELY_IMPORTANT,
/**
* {@link EventListener}s with
* this priority are called 2nd.
*
* @since v1-alpha9
*/
VERY_IMPORTANT,
/**
* {@link EventListener}s with
* this priority are called 3rd.
*
* @since v1-alpha9
*/
IMPORTANT,
/**
* {@link EventListener}s with
* this priority are called 4th.
*
* @since v1-alpha9
*/
DEFAULT,
/**
* {@link EventListener}s with
* this priority are called 5th.
*
* @since v1-alpha9
*/
UNIMPORTANT,
/**
* {@link EventListener}s with
* this priority are called 6th.
*
* @since v1-alpha9
*/
VERY_UNIMPORTANT,
/**
* {@link EventListener}s with this
* priority are called after all others.
* <p>
* This priority is exclusive to the
* engine and subsystems and should
* not be used by applications.
*
* @since v1-alpha9
*/
EXCLUSIVELY_UNIMPORTANT
}
}

View file

@ -20,7 +20,6 @@
package de.staropensource.engine.base.implementable;
import de.staropensource.engine.base.implementable.helper.EventHelper;
import de.staropensource.engine.base.type.EventPriority;
import org.jetbrains.annotations.NotNull;
/**
@ -39,7 +38,7 @@ public abstract class EventListenerCode {
*
* @since v1-alpha5
*/
public @NotNull EventPriority priority = EventPriority.DEFAULT;
public @NotNull Event.Priority priority = Event.Priority.DEFAULT;
/**
* Creates and initializes an instance of this abstract class.

View file

@ -32,8 +32,7 @@ import de.staropensource.engine.base.implementable.EventListenerCode;
import de.staropensource.engine.base.internal.implementation.EventListenerMethod;
import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.type.EventPriority;
import de.staropensource.engine.base.utility.ListFormatter;
import de.staropensource.engine.base.utility.misc.ListFormatter;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -78,7 +77,7 @@ public final class EventHelper {
* @see EngineInternals#getReflectiveClasspathScanning()
* @since v1-alpha5
*/
public static synchronized void registerEvent(@NotNull Class<? extends Event> event, @NotNull EventListenerCode eventListener, @NotNull EventPriority priority) {
public static synchronized void registerEvent(@NotNull Class<? extends Event> event, @NotNull EventListenerCode eventListener, @NotNull Event.Priority priority) {
if (EngineInternals.getInstance().getReflectiveClasspathScanning())
return;
@ -112,7 +111,7 @@ public final class EventHelper {
* @since v1-alpha5
*/
public static void registerEvent(@NotNull Class<? extends Event> event, @NotNull EventListenerCode eventListener) {
registerEvent(event, eventListener, EventPriority.DEFAULT);
registerEvent(event, eventListener, Event.Priority.DEFAULT);
}
/**

View file

@ -22,7 +22,7 @@ package de.staropensource.engine.base.implementation.versioning;
import de.staropensource.engine.base.implementable.VersioningSystem;
import de.staropensource.engine.base.exception.versioning.IncompatibleVersioningSystemException;
import de.staropensource.engine.base.exception.versioning.InvalidVersionStringException;
import de.staropensource.engine.base.utility.Miscellaneous;
import de.staropensource.engine.base.utility.misc.StringUtil;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range;
@ -98,7 +98,7 @@ public final class FourNumberVersioningSystem implements VersioningSystem {
*/
public FourNumberVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException {
String[] separatorList = new String[]{ ".", "-" };
String separator = Miscellaneous.getSeparator(versionString, separatorList, 3);
String separator = StringUtil.getSeparatorRequired(versionString, separatorList, 3);
// Escape separator or throw error if invalid
switch (separator) {

View file

@ -22,7 +22,7 @@ package de.staropensource.engine.base.implementation.versioning;
import de.staropensource.engine.base.implementable.VersioningSystem;
import de.staropensource.engine.base.exception.versioning.IncompatibleVersioningSystemException;
import de.staropensource.engine.base.exception.versioning.InvalidVersionStringException;
import de.staropensource.engine.base.utility.Miscellaneous;
import de.staropensource.engine.base.utility.misc.StringUtil;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -117,7 +117,7 @@ public final class SemanticVersioningSystem implements VersioningSystem {
*/
public SemanticVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException {
String[] separatorList = new String[]{ "." };
String separator = Miscellaneous.getSeparator(versionString, separatorList, 2);
String separator = StringUtil.getSeparatorRequired(versionString, separatorList, 2);
// Escape separator or throw error if invalid
switch (separator) {

View file

@ -22,7 +22,7 @@ package de.staropensource.engine.base.implementation.versioning;
import de.staropensource.engine.base.implementable.VersioningSystem;
import de.staropensource.engine.base.exception.versioning.IncompatibleVersioningSystemException;
import de.staropensource.engine.base.exception.versioning.InvalidVersionStringException;
import de.staropensource.engine.base.utility.Miscellaneous;
import de.staropensource.engine.base.utility.misc.StringUtil;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range;
@ -86,7 +86,7 @@ public final class ThreeNumberVersioningSystem implements VersioningSystem {
*/
public ThreeNumberVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException {
String[] separatorList = new String[]{ ".", "-" };
String separator = Miscellaneous.getSeparator(versionString, separatorList, 2);
String separator = StringUtil.getSeparatorRequired(versionString, separatorList, 2);
// Escape separator or throw error if invalid
switch (separator) {

View file

@ -22,7 +22,7 @@ package de.staropensource.engine.base.implementation.versioning;
import de.staropensource.engine.base.implementable.VersioningSystem;
import de.staropensource.engine.base.exception.versioning.IncompatibleVersioningSystemException;
import de.staropensource.engine.base.exception.versioning.InvalidVersionStringException;
import de.staropensource.engine.base.utility.Miscellaneous;
import de.staropensource.engine.base.utility.misc.StringUtil;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range;
@ -74,7 +74,7 @@ public final class TwoNumberVersioningSystem implements VersioningSystem {
*/
public TwoNumberVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException {
String[] separatorList = new String[]{ ".", "-" };
String separator = Miscellaneous.getSeparator(versionString, separatorList, 1);
String separator = StringUtil.getSeparatorRequired(versionString, separatorList, 1);
// Escape separator or throw error if invalid
switch (separator) {

View file

@ -20,7 +20,7 @@
package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.Placeholder;
import de.staropensource.engine.base.utility.Math;
import de.staropensource.engine.base.utility.misc.NumberUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Calendar;
@ -43,6 +43,6 @@ public final class DateDay implements Placeholder {
/** {@inheritDoc} */
@Override
public @NotNull String replace(@NotNull String text) {
return text.replace("%date_day%", Math.padNumbers(Calendar.getInstance().get(Calendar.DAY_OF_MONTH), 2));
return text.replace("%date_day%", NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.DAY_OF_MONTH), 2));
}
}

View file

@ -20,7 +20,7 @@
package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.Placeholder;
import de.staropensource.engine.base.utility.Math;
import de.staropensource.engine.base.utility.misc.NumberUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Calendar;
@ -43,6 +43,6 @@ public final class DateMonth implements Placeholder {
/** {@inheritDoc} */
@Override
public @NotNull String replace(@NotNull String text) {
return text.replace("%date_month%", Math.padNumbers(Calendar.getInstance().get(Calendar.MONTH), 2));
return text.replace("%date_month%", NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.MONTH), 2));
}
}

View file

@ -20,7 +20,7 @@
package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.Placeholder;
import de.staropensource.engine.base.utility.Math;
import de.staropensource.engine.base.utility.misc.NumberUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Calendar;
@ -43,6 +43,6 @@ public final class DateYear implements Placeholder {
/** {@inheritDoc} */
@Override
public @NotNull String replace(@NotNull String text) {
return text.replace("%date_year%", Math.padNumbers(Calendar.getInstance().get(Calendar.YEAR), 4));
return text.replace("%date_year%", NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.YEAR), 4));
}
}

View file

@ -20,7 +20,7 @@
package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.Placeholder;
import de.staropensource.engine.base.utility.Math;
import de.staropensource.engine.base.utility.misc.NumberUtil;
import org.jetbrains.annotations.NotNull;
/**
@ -42,6 +42,6 @@ public final class TimeEpoch implements Placeholder {
/** {@inheritDoc} */
@Override
public @NotNull String replace(@NotNull String text) {
return text.replace("%time_epoch%", Math.padNumbers(System.currentTimeMillis(), String.valueOf(Long.MAX_VALUE).length()));
return text.replace("%time_epoch%", NumberUtil.padNumbers(System.currentTimeMillis(), String.valueOf(Long.MAX_VALUE).length()));
}
}

View file

@ -20,7 +20,7 @@
package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.Placeholder;
import de.staropensource.engine.base.utility.Math;
import de.staropensource.engine.base.utility.misc.NumberUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Calendar;
@ -43,6 +43,6 @@ public final class TimeHour implements Placeholder {
/** {@inheritDoc} */
@Override
public @NotNull String replace(@NotNull String text) {
return text.replace("%time_hour%", Math.padNumbers(Calendar.getInstance().get(Calendar.HOUR_OF_DAY), 2));
return text.replace("%time_hour%", NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.HOUR_OF_DAY), 2));
}
}

View file

@ -20,7 +20,7 @@
package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.Placeholder;
import de.staropensource.engine.base.utility.Math;
import de.staropensource.engine.base.utility.misc.NumberUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Calendar;
@ -43,6 +43,6 @@ public final class TimeMinute implements Placeholder {
/** {@inheritDoc} */
@Override
public @NotNull String replace(@NotNull String text) {
return text.replace("%time_minute%", Math.padNumbers(Calendar.getInstance().get(Calendar.MINUTE), 2));
return text.replace("%time_minute%", NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.MINUTE), 2));
}
}

View file

@ -20,7 +20,7 @@
package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.Placeholder;
import de.staropensource.engine.base.utility.Math;
import de.staropensource.engine.base.utility.misc.NumberUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Calendar;
@ -43,6 +43,6 @@ public final class TimeSecond implements Placeholder {
/** {@inheritDoc} */
@Override
public @NotNull String replace(@NotNull String text) {
return text.replace("%time_second%", Math.padNumbers(Calendar.getInstance().get(Calendar.SECOND), 2));
return text.replace("%time_second%", NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.SECOND), 2));
}
}

View file

@ -19,15 +19,12 @@
package de.staropensource.engine.base.logging;
import de.staropensource.engine.base.EngineConfiguration;
import de.staropensource.engine.base.implementable.LoggingAdapter;
import de.staropensource.engine.base.implementation.logging.PlainLoggingAdapter;
import de.staropensource.engine.base.internal.type.QueuedLogCall;
import de.staropensource.engine.base.logging.backend.CrashHandler;
import de.staropensource.engine.base.logging.backend.Filterer;
import de.staropensource.engine.base.logging.backend.Processor;
import de.staropensource.engine.base.logging.backend.async.LoggingQueue;
import de.staropensource.engine.base.type.immutable.ImmutableArrayList;
import de.staropensource.engine.base.type.logging.LogLevel;
import lombok.Getter;
import lombok.Setter;
@ -35,8 +32,6 @@ import org.intellij.lang.annotations.RegExp;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* The frontend class for sos!engine's logging system.
*

View file

@ -24,8 +24,8 @@ import de.staropensource.engine.base.EngineConfiguration;
import de.staropensource.engine.base.EngineInternals;
import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.type.logging.LogLevel;
import de.staropensource.engine.base.utility.Math;
import de.staropensource.engine.base.utility.Miscellaneous;
import de.staropensource.engine.base.utility.misc.NumberUtil;
import de.staropensource.engine.base.utility.misc.Miscellaneous;
import de.staropensource.engine.base.utility.information.EngineInformation;
import de.staropensource.engine.base.utility.information.JvmInformation;
import org.jetbrains.annotations.NotNull;
@ -110,9 +110,9 @@ public final class CrashHandler {
else
output
.append("\n")
.append(Miscellaneous.getStackTraceHeader(throwable))
.append(Miscellaneous.getThrowableHeader(throwable))
.append("\n")
.append(Miscellaneous.getStackTraceAsString(throwable, true))
.append(Miscellaneous.stackTraceAsString(throwable, true))
.append("\n");
output.append("\nMessage: \n")
@ -123,23 +123,23 @@ public final class CrashHandler {
output
.append("---- Environment ----")
.append("\nTime and date: ")
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.DAY_OF_MONTH), 2))
.append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.DAY_OF_MONTH), 2))
.append(".")
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.MONTH), 2))
.append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.MONTH), 2))
.append(".")
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.YEAR), 4))
.append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.YEAR), 4))
.append(" ")
.append(de.staropensource.engine.base.utility.Math.padNumbers(Calendar.getInstance().get(Calendar.HOUR_OF_DAY), 2))
.append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.HOUR_OF_DAY), 2))
.append(":")
.append(de.staropensource.engine.base.utility.Math.padNumbers(Calendar.getInstance().get(Calendar.MINUTE), 2))
.append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.MINUTE), 2))
.append(":")
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.SECOND), 2))
.append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.SECOND), 2))
.append(" [")
.append(TimeZone.getDefault().getDisplayName(false, TimeZone.SHORT, Locale.US))
.append("]")
.append("\nUNIX Epoch: ")
.append(Math.padNumbers(System.currentTimeMillis(), String.valueOf(Long.MAX_VALUE).length()))
.append(NumberUtil.padNumbers(System.currentTimeMillis(), String.valueOf(Long.MAX_VALUE).length()))
.append("\nOperating system: ")
.append(System.getProperty("os.name"))
@ -293,7 +293,7 @@ public final class CrashHandler {
.append(thread.isDaemon())
.append("):")
.append("\n")
.append(Miscellaneous.getStackTraceAsString(stacktraces.get(thread), false))
.append(Miscellaneous.stackTraceAsString(stacktraces.get(thread), false))
.append("\n");
}
output.append("\n");

View file

@ -24,7 +24,7 @@ import de.staropensource.engine.base.implementation.shortcode.EmptyShortcodePars
import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.logging.backend.async.LoggingQueue;
import de.staropensource.engine.base.type.logging.LogLevel;
import de.staropensource.engine.base.utility.Math;
import de.staropensource.engine.base.utility.misc.NumberUtil;
import de.staropensource.engine.base.utility.PlaceholderEngine;
import de.staropensource.engine.base.utility.information.JvmInformation;
import org.jetbrains.annotations.NotNull;
@ -213,11 +213,11 @@ public final class Processor {
private static void time(@NotNull StringBuilder builder) {
if (isFeatureEnabled("time"))
builder
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.HOUR_OF_DAY), 2))
.append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.HOUR_OF_DAY), 2))
.append(":")
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.MINUTE), 2))
.append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.MINUTE), 2))
.append(":")
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.SECOND), 2));
.append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.SECOND), 2));
}
/**
@ -229,11 +229,11 @@ public final class Processor {
private static void date(@NotNull StringBuilder builder) {
if (isFeatureEnabled("date"))
builder
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.DAY_OF_MONTH), 2))
.append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.DAY_OF_MONTH), 2))
.append(".")
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.MONTH), 2))
.append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.MONTH), 2))
.append(".")
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.YEAR), 4));
.append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.YEAR), 4));
}
/**

View file

@ -21,7 +21,6 @@ package de.staropensource.engine.base.logging.backend.async;
import de.staropensource.engine.base.internal.type.QueuedLogCall;
import de.staropensource.engine.base.logging.backend.Processor;
import de.staropensource.engine.base.type.immutable.ImmutableArrayList;
import de.staropensource.engine.base.type.logging.LogLevel;
import org.jetbrains.annotations.NotNull;
@ -67,8 +66,8 @@ public final class LoggingQueue {
* @since v1-alpha8
*/
public static void flush() {
// Get copy of and clear queue
List<@NotNull QueuedLogCall> queue = new ImmutableArrayList<>(LoggingQueue.queue);
// Get copy of and clear the queue
List<@NotNull QueuedLogCall> queue = new ArrayList<>(LoggingQueue.queue);
LoggingQueue.queue.clear();
for (QueuedLogCall queuedCall : queue)

View file

@ -20,7 +20,7 @@
package de.staropensource.engine.base.type;
import de.staropensource.engine.base.EngineConfiguration;
import de.staropensource.engine.base.utility.Math;
import de.staropensource.engine.base.utility.misc.NumberUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
@ -42,7 +42,7 @@ import java.util.Locale;
@Getter
@Setter
@SuppressWarnings({ "JavadocDeclaration" })
public final class Color {
public class Color {
/**
* Contains the red color value.
*
@ -118,10 +118,10 @@ public final class Color {
* @since v1-alpha6
*/
private Color(int red, int green, int blue, int alpha) {
this.red = Math.boundNumber(0, 255, red);
this.green = Math.boundNumber(0, 255, green);
this.blue = Math.boundNumber(0, 255, blue);
this.alpha = Math.boundNumber(0, 255, alpha);
this.red = NumberUtil.limitNumber(0, 255, red);
this.green = NumberUtil.limitNumber(0, 255, green);
this.blue = NumberUtil.limitNumber(0, 255, blue);
this.alpha = NumberUtil.limitNumber(0, 255, alpha);
}
/**

View file

@ -1,81 +0,0 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Authors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.type;
import de.staropensource.engine.base.annotation.EventListener;
/**
* Allows an {@link EventListener} method to specify when it should be invoked.
*
* @since v1-alpha0
*/
@SuppressWarnings({ "unused" })
public enum EventPriority {
/**
* {@link EventListener}s with this priority are processed first, even before {@link #VERY_IMPORTANT}.
* This event is exclusive to subsystems and should not be used by applications.
*
* @since v1-alpha0
*/
EXCLUSIVELY_IMPORTANT,
/**
* {@link EventListener}s with this priority are invoked first.
*
* @since v1-alpha0
*/
VERY_IMPORTANT,
/**
* {@link EventListener}s with this priority are invoked second.
*
* @since v1-alpha0
*/
IMPORTANT,
/**
* The default event priority, {@link EventListener}s with this priority are invoked third.
*
* @since v1-alpha0
*/
DEFAULT,
/**
* {@link EventListener}s with this priority are invoked fourth.
*
* @since v1-alpha0
*/
UNIMPORTANT,
/**
* {@link EventListener}s with this priority are invoked last.
*
* @since v1-alpha0
*/
VERY_UNIMPORTANT,
/**
* {@link EventListener}s with this priority are invoked last, even after {@link #VERY_UNIMPORTANT}.
* This event is exclusive to subsystems and should not be used by applications.
*
* @since v1-alpha0
*/
EXCLUSIVELY_UNIMPORTANT
}

View file

@ -29,32 +29,32 @@ import org.jetbrains.annotations.NotNull;
*/
public enum Tristate {
/**
* An unset tristate.
* Defines an unset state.
*
* @since v1-alpha1
*/
UNSET,
/**
* A true tristate.
* Defines a true state.
*
* @since v1-alpha1
*/
TRUE,
/**
* A false tristate.
* Defines a false state.
*
* @since v1-alpha1
*/
FALSE;
/**
* Converts the {@link Boolean} into a {@link Tristate}.
* Converts the specified {@link Boolean} into a {@link Tristate}.
*
* @param bool boolean to convert
* @return tristated boolean
* @since v1-alpha5
* @return {@link Tristate} representation of the specified boolean
* @since v1-alpha9
*/
public static @NotNull Tristate toTristate(boolean bool) {
if (bool) return Tristate.TRUE;
@ -62,12 +62,28 @@ public enum Tristate {
}
/**
* Converts the {@link Tristate} into a {@link Boolean}.
* Converts the specified {@link Integer} into a {@link Tristate}.
*
* @param integer integer to convert
* @return {@link Tristate} representation of the specified integer
* @since v1-alpha9
*/
public static @NotNull Tristate toTristate(int integer) {
return switch (integer) {
case 0 -> Tristate.FALSE;
case 1 -> Tristate.TRUE;
case 2 -> Tristate.UNSET;
default -> throw new IndexOutOfBoundsException("Supplied integer '" + integer + "' is not in range 0-2");
};
}
/**
* Converts this {@link Tristate} into a {@link Boolean}.
* Make sure to check for {@link #UNSET} first.
*
* @return booleanized {@link Tristate}
* @throws TristateConversionException when encountering {@link #UNSET}
* @since v1-alpha2
* @return trimmed boolean representation of this {@link Tristate}
* @throws TristateConversionException on encountering {@link #UNSET}
* @since v1-alpha9
*/
public boolean toBoolean() {
return switch (this) {
@ -76,4 +92,19 @@ public enum Tristate {
case FALSE -> false;
};
}
/**
* Converts this {@link Tristate} into an {@link Integer}.
*
* @return integer representation of this {@link Tristate}
* @throws TristateConversionException when encountering {@link #UNSET}
* @since v1-alpha9
*/
public int toInteger() {
return switch (this) {
case FALSE -> 0;
case TRUE -> 1;
case UNSET -> 2;
};
}
}

View file

@ -22,7 +22,8 @@ package de.staropensource.engine.base.type;
import de.staropensource.engine.base.implementation.versioning.StarOpenSourceVersioningSystem;
/**
* Provides all available version types specified in the StarOpenSource Versioning System v2.
* Provides all available version types as specified
* by the StarOpenSource Versioning System v2.
*
* @see StarOpenSourceVersioningSystem
* @since v1-alpha0

View file

@ -1,222 +0,0 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Authors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.type.immutable;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.function.UnaryOperator;
/**
* An unmodifiable {@link ArrayList}.
*
* @param <E> contained type
* @since v1-alpha1
*/
@SuppressWarnings({ "unused" })
public class ImmutableArrayList<E> extends ArrayList<E> {
/**
* Creates and initializes an instance of this class.
*
* @since v1-alpha1
*/
public ImmutableArrayList() {}
/**
* Creates and initializes an instance of this class.
* Converts a {@link LinkedList} into an {@link ImmutableArrayList}.
*
* @param list {@link List} to convert
* @since v1-alpha1
*/
public ImmutableArrayList(@NotNull List<E> list) {
super.addAll(list);
}
/**
* Converts the {@link ImmutableArrayList} into a regular {@link ArrayList}.
*
* @return mutable {@link ArrayList}
* @since v1-alpha2
*/
public @NotNull ArrayList<E> toMutable() {
return new ArrayList<>(this);
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public boolean add(E e) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public boolean addAll(@NotNull Collection<? extends E> c) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public boolean addAll(int index, @NotNull Collection<? extends E> c) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public boolean removeAll(@NotNull Collection<?> c) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public boolean retainAll(@NotNull Collection<?> c) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public void replaceAll(UnaryOperator<E> operator) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public void sort(Comparator<? super E> c) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public void clear() {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public E set(int index, E element) throws UnsupportedOperationException {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public void add(int index, E element) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public E remove(int index) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public void addFirst(E e) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public void addLast(E e) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public E removeFirst() {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public E removeLast() {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableArrayList");
}
}

View file

@ -1,167 +0,0 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Authors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.type.immutable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;
/**
* An unmodifiable {@link HashMap}.
*
* @param <K> contained key type
* @param <V> contained value type
* @since v1-alpha1
*/
@SuppressWarnings({ "unused" })
public class ImmutableHashMap<K, V> extends HashMap<K, V> {
/**
* Creates and initializes an instance of this class.
*
* @since v1-alpha1
*/
public ImmutableHashMap() {}
/**
* Creates and initializes an instance of this class.
* Converts a {@link Map} into an {@link ImmutableHashMap}.
*
* @param map {@link Map} to convert
* @since v1-alpha1
*/
public ImmutableHashMap(@NotNull Map<K, V> map) {
for (K key : map.keySet())
super.put(key, map.get(key));
}
/**
* Converts the {@link ImmutableHashMap} into a regular {@link HashMap}.
*
* @return mutable {@link HashMap}
* @since v1-alpha2
*/
public @NotNull HashMap<K, V> toMutable() {
return new HashMap<>(this);
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, hash map is immutable
*/
@Override
public @Nullable V put(K key, V value) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, hash map is immutable
*/
@Override
public @Nullable V remove(Object key) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, hash map is immutable
*/
@Override
public void putAll(@NotNull Map<? extends K, ? extends V> m) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, hash map is immutable
*/
@Override
public void clear() {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, hash map is immutable
*/
@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, hash map is immutable
*/
@Override
public @Nullable V putIfAbsent(K key, V value) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, hash map is immutable
*/
@Override
public boolean remove(Object key, Object value) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, hash map is immutable
*/
@Override
public boolean replace(K key, V oldValue, V newValue) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, hash map is immutable
*/
@Override
public @Nullable V replace(K key, V value) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, hash map is immutable
*/
@Override
public @Nullable V merge(K key, @NotNull V value, @NotNull BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashMap");
}
}

View file

@ -1,134 +0,0 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Authors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.type.immutable;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
/**
* An unmodifiable {@link HashSet}.
*
* @param <E> contained type
* @since v1-alpha2
*/
@SuppressWarnings({ "unused" })
public class ImmutableHashSet<E> extends HashSet<E> {
/**
* Creates and initializes an instance of this class.
*
* @since v1-alpha2
*/
public ImmutableHashSet() {}
/**
* Creates and initializes an instance of this class.
* Converts a {@link Set} into an {@link ImmutableHashSet}.
*
* @param set {@link Set} to convert
* @since v1-alpha2
*/
public ImmutableHashSet(@NotNull Set<E> set) {
super.addAll(set);
}
/**
* Converts the {@link ImmutableHashSet} into a regular {@link HashSet}.
*
* @return mutable {@link HashSet}
* @since v1-alpha2
*/
public @NotNull HashSet<E> toMutable() {
return new HashSet<>(this);
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public boolean add(Object o) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashSet");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashSet");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public boolean addAll(@NotNull Collection collection) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashSet");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public boolean retainAll(@NotNull Collection collection) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashSet");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public boolean removeIf(Predicate filter) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashSet");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public void clear() {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashSet");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, array list is immutable
*/
@Override
public boolean removeAll(@NotNull Collection collection) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableHashSet");
}
}

View file

@ -1,167 +0,0 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Authors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.type.immutable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.BiFunction;
/**
* An unmodifiable {@link Map}.
*
* @param <K> contained key type
* @param <V> contained value type
* @since v1-alpha1
*/
@SuppressWarnings({ "unused" })
public class ImmutableLinkedHashMap<K, V> extends LinkedHashMap<K, V> {
/**
* Creates and initializes an instance of this class.
*
* @since v1-alpha1
*/
public ImmutableLinkedHashMap() {}
/**
* Creates and initializes an instance of this class.
* Converts a {@link Map} into an {@link ImmutableLinkedHashMap}.
*
* @param map {@link Map} to convert
* @since v1-alpha1
*/
public ImmutableLinkedHashMap(@NotNull Map<K, V> map) {
for (K key : map.keySet())
super.put(key, map.get(key));
}
/**
* Converts the {@link ImmutableLinkedHashMap} into a regular {@link LinkedHashMap}.
*
* @return mutable {@link LinkedHashMap}
* @since v1-alpha2
*/
public @NotNull LinkedHashMap<K, V> toMutable() {
return new LinkedHashMap<>(this);
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked hash map is immutable
*/
@Override
public @Nullable V put(K key, V value) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked hash map is immutable
*/
@Override
public @Nullable V remove(Object key) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked hash map is immutable
*/
@Override
public void putAll(@NotNull Map<? extends K, ? extends V> m) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked hash map is immutable
*/
@Override
public void clear() {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked hash map is immutable
*/
@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked hash map is immutable
*/
@Override
public @Nullable V putIfAbsent(K key, V value) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked hash map is immutable
*/
@Override
public boolean remove(Object key, Object value) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked hash map is immutable
*/
@Override
public boolean replace(K key, V oldValue, V newValue) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked hash map is immutable
*/
@Override
public @Nullable V replace(K key, V value) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedHashMap");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked hash map is immutable
*/
@Override
public @Nullable V merge(K key, @NotNull V value, @NotNull BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedHashMap");
}
}

View file

@ -1,222 +0,0 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Authors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.type.immutable;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.function.UnaryOperator;
/**
* An unmodifiable {@link LinkedList}.
*
* @param <E> contained type
* @since v1-alpha1
*/
@SuppressWarnings({ "unused" })
public class ImmutableLinkedList<E> extends LinkedList<E> {
/**
* Creates and initializes an instance of this class.
*
* @since v1-alpha1
*/
public ImmutableLinkedList() {}
/**
* Creates and initializes an instance of this class.
* Converts a {@link LinkedList} into an {@link ImmutableLinkedList}.
*
* @param list {@link List} to convert
* @since v1-alpha1
*/
public ImmutableLinkedList(@NotNull List<E> list) {
super.addAll(size(), list);
}
/**
* Converts the {@link ImmutableLinkedList} into a regular {@link LinkedList}.
*
* @return mutable {@link LinkedList}
* @since v1-alpha2
*/
public @NotNull LinkedList<E> toMutable() {
return new LinkedList<>(this);
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public boolean add(E e) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public boolean addAll(@NotNull Collection<? extends E> c) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public boolean addAll(int index, @NotNull Collection<? extends E> c) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public boolean removeAll(@NotNull Collection<?> c) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public boolean retainAll(@NotNull Collection<?> c) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public void replaceAll(UnaryOperator<E> operator) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public void sort(Comparator<? super E> c) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public void clear() {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public E set(int index, E element) throws UnsupportedOperationException {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public void add(int index, E element) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public E remove(int index) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public void addFirst(E e) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public void addLast(E e) {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public E removeFirst() {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
/**
* {@inheritDoc}
*
* @throws UnsupportedOperationException always, linked list is immutable
*/
@Override
public E removeLast() {
throw new UnsupportedOperationException("This method cannot be executed on an ImmutableLinkedList");
}
}

View file

@ -1,68 +0,0 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Authors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.type.logging;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Defines a rule used during logging to allow or prevent certain log calls.
*
* @since v1-alpha1
*/
@Getter
@SuppressWarnings({ "JavadocDeclaration" })
public abstract class LogRule {
/**
* Contains if the log rule should disallow or permit matching log calls.
*
* @see LogRuleType
* @since v1-alpha1
* -- GETTER --
* Returns if the log rule should disallow or permit matching log calls.
*
* @return rule type
* @see LogRuleType
* @since v1-alpha1
*/
private final @NotNull LogRuleType type;
/**
* Creates and initializes an instance of this abstract class.
*
* @param type rule type
*/
public LogRule(@NotNull LogRuleType type) {
this.type = type;
}
/**
* Evaluates the rule and returns if the rule matches.
*
* @param level level
* @param issuerClass class of the issuer
* @param issuerOrigin origin of the issuer
* @param issuerMetadata metadata about the issuer
* @param message raw message
* @return if the rule matches
*/
public abstract boolean evaluate(@NotNull LogLevel level, @NotNull Class<?> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message);
}

View file

@ -1,43 +0,0 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Authors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.type.logging;
/**
* Used for determining if a {@link LogRule} should allow (whitelist) or prevent (blacklist) log call processing.
*
* @since v1-alpha1
*/
public enum LogRuleType {
/**
* Indicates that log calls matching this rule will always be allowed, even if blacklisted.
*
* @see #BLACKLIST
* @since v1-alpha1
*/
WHITELIST,
/**
* Indicates that log calls matching this will always be disallowed except when whitelisted.
*
* @see #WHITELIST
* @since v1-alpha1
*/
BLACKLIST
}

View file

@ -22,7 +22,7 @@ package de.staropensource.engine.base.utility;
import de.staropensource.engine.base.Engine;
import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.type.EngineState;
import de.staropensource.engine.base.type.FileType;
import de.staropensource.engine.base.utility.misc.Miscellaneous;
import lombok.Getter;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@ -190,7 +190,7 @@ public final class FileAccess {
if (Files.exists(path))
Logger.error("Deleting file or directory \"" + path + "\" failed");
} catch (Exception exception) {
Logger.error("File or directory \"" + path + "\" could not be deleted\n" + Miscellaneous.getStackTraceHeader(exception) + "\n" + Miscellaneous.getStackTraceAsString(exception, true));
Logger.error("File or directory \"" + path + "\" could not be deleted\n" + Miscellaneous.getThrowableHeader(exception) + "\n" + Miscellaneous.stackTraceAsString(exception, true));
}
}
}
@ -267,15 +267,15 @@ public final class FileAccess {
* @return file type
* @since v1-alpha8
*/
public @NotNull FileType getType() {
public @NotNull FileAccess.Type getType() {
if (!exists())
return FileType.VOID;
return Type.VOID;
else if (Files.isRegularFile(path))
return FileType.FILE;
return Type.FILE;
else if (Files.isDirectory(path))
return FileType.DIRECTORY;
return Type.DIRECTORY;
else
return FileType.UNKNOWN;
return Type.UNKNOWN;
}
/**
@ -309,7 +309,7 @@ public final class FileAccess {
* @since v1-alpha8
*/
public @NotNull String @NotNull [] listContents() throws UnsupportedOperationException, IOException {
if (getType() != FileType.DIRECTORY)
if (getType() != Type.DIRECTORY)
throw new UnsupportedOperationException("The file \"" + path + "\" is not a directory");
String[] list = file.list();
@ -661,7 +661,7 @@ public final class FileAccess {
* Returns the contents of this file.
* <p>
* Returns an empty array if this file
* is not of type {@link FileType#FILE}.
* is not of type {@link Type#FILE}.
*
* @return file contents in bytes
* @throws IOException on an IO error
@ -669,7 +669,7 @@ public final class FileAccess {
* @since v1-alpha8
*/
public byte @NotNull [] readBytes() throws IOException, OutOfMemoryError {
if (getType() != FileType.FILE)
if (getType() != Type.FILE)
return new byte[0];
Logger.diag("Reading file \"" + path + "\" (bytes)");
@ -680,7 +680,7 @@ public final class FileAccess {
* Returns the contents of this file.
* <p>
* Returns an empty list if this file
* is not of type {@link FileType#FILE}.
* is not of type {@link Type#FILE}.
*
* @return file contents in bytes
* @throws IOException on an IO error
@ -688,7 +688,7 @@ public final class FileAccess {
* @since v1-alpha8
*/
public @NotNull List<@NotNull String> readLines() throws IOException, OutOfMemoryError {
if (getType() != FileType.FILE)
if (getType() != Type.FILE)
return new ArrayList<>();
Logger.diag("Reading file \"" + path + "\" (lines)");
@ -701,7 +701,7 @@ public final class FileAccess {
* {@link StandardCharsets#UTF_8} character set.
* <p>
* Returns an empty string if this file
* is not of type {@link FileType#FILE}.
* is not of type {@link Type#FILE}.
*
* @return file contents as a string
* @throws IOException on an IO error
@ -716,7 +716,7 @@ public final class FileAccess {
* Returns the contents of this file.
* <p>
* Returns an empty string if this file
* is not of type {@link FileType#FILE}.
* is not of type {@link Type#FILE}.
*
* @param charset charset to decode the bytes with
* @return file contents as a string
@ -725,7 +725,7 @@ public final class FileAccess {
* @since v1-alpha8
*/
public @NotNull String readContent(@NotNull Charset charset) throws IOException, OutOfMemoryError {
if (getType() != FileType.FILE)
if (getType() != Type.FILE)
return "";
Logger.diag("Reading file \"" + path + "\" (string)");
@ -739,15 +739,15 @@ public final class FileAccess {
*
* @param bytes bytes to write
* @param async allows the operating system to decide when to flush the file to disk if {@code true}, flushes the data to disk immediately if {@code false}
* @throws UnsupportedOperationException if the type of this file is neither {@link FileType#VOID} or {@link FileType#FILE}
* @throws UnsupportedOperationException if the type of this file is neither {@link Type#VOID} or {@link Type#FILE}
* @throws IOException on an IO error
* @return this instance
*/
public @NotNull FileAccess writeBytes(byte @NotNull [] bytes, boolean async) throws UnsupportedOperationException, IOException {
if (getType() == FileType.VOID)
if (getType() == Type.VOID)
createFile();
else if (getType() != FileType.FILE)
throw new UnsupportedOperationException("File \"" + path + "\" is not of type FileType.VOID or FileType.FILE");
else if (getType() != Type.FILE)
throw new UnsupportedOperationException("File \"" + path + "\" is not of type Type.VOID or Type.FILE");
createFile();
Logger.diag("Writing file \"" + path + "\" (bytes, " + (async ? "async" : "dsync") + ")");
@ -762,7 +762,7 @@ public final class FileAccess {
*
* @param string string to write
* @param async allows the operating system to decide when to flush the file to disk if {@code true}, flushes the data to disk immediately if {@code false}
* @throws UnsupportedOperationException if the type of this file is neither {@link FileType#VOID} or {@link FileType#FILE}
* @throws UnsupportedOperationException if the type of this file is neither {@link Type#VOID} or {@link Type#FILE}
* @throws IOException on an IO error
* @return this instance
*/
@ -776,15 +776,15 @@ public final class FileAccess {
* @param string string to write
* @param charset charset to encode the string in
* @param async allows the operating system to decide when to flush the file to disk if {@code true}, flushes the data to disk immediately if {@code false}
* @throws UnsupportedOperationException if the type of this file is neither {@link FileType#VOID} or {@link FileType#FILE}
* @throws UnsupportedOperationException if the type of this file is neither {@link Type#VOID} or {@link Type#FILE}
* @throws IOException on an IO error
* @return this instance
*/
public @NotNull FileAccess writeString(@NotNull String string, @NotNull Charset charset, boolean async) throws UnsupportedOperationException, IOException {
if (getType() == FileType.VOID)
if (getType() == Type.VOID)
createFile();
else if (getType() != FileType.FILE)
throw new UnsupportedOperationException("File \"" + path + "\" is not of type FileType.VOID or FileType.FILE");
else if (getType() != Type.FILE)
throw new UnsupportedOperationException("File \"" + path + "\" is not of type Type.VOID or Type.FILE");
Logger.diag("Writing file \"" + path + "\" (string, " + (async ? "async" : "dsync") + ")");
Files.writeString(path, string, charset, StandardOpenOption.WRITE, async ? StandardOpenOption.DSYNC : StandardOpenOption.SYNC);
@ -798,15 +798,15 @@ public final class FileAccess {
*
* @param bytes bytes to append
* @param async allows the operating system to decide when to flush the file to disk if {@code true}, flushes the data to disk immediately if {@code false}
* @throws UnsupportedOperationException if the type of this file is neither {@link FileType#VOID} or {@link FileType#FILE}
* @throws UnsupportedOperationException if the type of this file is neither {@link Type#VOID} or {@link Type#FILE}
* @throws IOException on an IO error
* @return this instance
*/
public @NotNull FileAccess appendBytes(byte @NotNull [] bytes, boolean async) throws UnsupportedOperationException, IOException {
if (getType() == FileType.VOID)
if (getType() == Type.VOID)
createFile();
else if (getType() != FileType.FILE)
throw new UnsupportedOperationException("File \"" + path + "\" is not of type FileType.VOID or FileType.FILE");
else if (getType() != Type.FILE)
throw new UnsupportedOperationException("File \"" + path + "\" is not of type Type.VOID or Type.FILE");
Logger.diag("Appending file \"" + path + "\" (bytes, " + (async ? "async" : "dsync") + ")");
Files.write(path, bytes, StandardOpenOption.APPEND, async ? StandardOpenOption.DSYNC : StandardOpenOption.SYNC);
@ -820,7 +820,7 @@ public final class FileAccess {
*
* @param string string to append
* @param async allows the operating system to decide when to flush the file to disk if {@code true}, flushes the data to disk immediately if {@code false}
* @throws UnsupportedOperationException if the type of this file is neither {@link FileType#VOID} or {@link FileType#FILE}
* @throws UnsupportedOperationException if the type of this file is neither {@link Type#VOID} or {@link Type#FILE}
* @throws IOException on an IO error
* @return this instance
*/
@ -834,18 +834,53 @@ public final class FileAccess {
* @param string string to append
* @param charset charset to encode the string in
* @param async allows the operating system to decide when to flush the file to disk if {@code true}, flushes the data to disk immediately if {@code false}
* @throws UnsupportedOperationException if the type of this file is neither {@link FileType#VOID} or {@link FileType#FILE}
* @throws UnsupportedOperationException if the type of this file is neither {@link Type#VOID} or {@link Type#FILE}
* @throws IOException on an IO error
* @return this instance
*/
public @NotNull FileAccess appendString(@NotNull String string, @NotNull Charset charset, boolean async) throws UnsupportedOperationException, IOException {
if (getType() == FileType.VOID)
if (getType() == Type.VOID)
createFile();
else if (getType() != FileType.FILE)
throw new UnsupportedOperationException("File \"" + path + "\" is not of type FileType.VOID or FileType.FILE");
else if (getType() != Type.FILE)
throw new UnsupportedOperationException("File \"" + path + "\" is not of type Type.VOID or Type.FILE");
Logger.diag("Appending file \"" + path + "\" (string, " + (async ? "async" : "dsync") + ")");
Files.writeString(path, string, charset, StandardOpenOption.APPEND, async ? StandardOpenOption.DSYNC : StandardOpenOption.SYNC);
return this;
}
/**
* Represents various file types.
*
* @since v1-alpha8
*/
public enum Type {
/**
* The path does not exist.
*
* @since v1-alpha8
*/
VOID,
/**
* It's a regular file.
*
* @since v1-alpha8
*/
FILE,
/**
* It's a directory containing files.
*
* @since v1-alpha8
*/
DIRECTORY,
/**
* The file type is unknown to the sos!engine.
*
* @since v1-alpha8
*/
UNKNOWN
}
}

View file

@ -1,254 +0,0 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Authors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.utility;
import de.staropensource.engine.base.event.ThrowableCatchEvent;
import de.staropensource.engine.base.exception.TristateConversionException;
import de.staropensource.engine.base.type.Tristate;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Range;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.stream.Collectors;
/**
* Contains smaller functions that don't fit into other utility classes.
*
* @since v1-alpha0
*/
@SuppressWarnings({ "unused" })
public final class Miscellaneous {
/**
* Creates and initializes an instance of this class.
*
* @since v1-alpha6
*/
private Miscellaneous() {}
/**
* Converts a boolean into an integer.
*
* @param bool boolean to convert
* @return converted integer
* @since v1-alpha2
*/
@Range(from = 0, to = 1)
public static int getIntegerizedBoolean(boolean bool) {
return bool ? 1 : 0;
}
/**
* Converts an integer into a {@link Tristate}.
*
* @param integer integer to convert
* @return expected boolean result, except if neither {@code 0} or {@code 1}, in which case {@link Tristate#UNSET} is returned
* @since v1-alpha2
*/
public static Tristate getTristatedInteger(@Range(from = 0, to = 1) int integer) {
return switch (integer) {
case 0 -> Tristate.TRUE;
case 1 -> Tristate.FALSE;
default -> Tristate.UNSET;
};
}
/**
* Converts an integer into a {@link Tristate} and then into a boolean.
*
* @param integer integer to convert
* @return booleanized integer
* @throws TristateConversionException when encountering {@link Tristate#UNSET}.
* @since v1-alpha2
*/
public static boolean getBooleanizedInteger(@Range(from = 0, to = 1) int integer) throws TristateConversionException {
return getTristatedInteger(integer).toBoolean();
}
/**
* Searches for a value in a {@link Map}.
*
* @param map map to use
* @param value value to search for
* @return all keys matching the specified value
* @since v1-alpha0
*/
public static Set<?> getMapValues(@NotNull Map<?, ?> map, @Nullable Object value) {
return map
.entrySet().stream()
.filter(entry -> Objects.equals(entry.getValue(), value))
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
/**
* Counts the occurrences of a substring inside of a string.
*
* @param string string to search
* @param substring substring to search for
* @return occurrences
*/
public static long countOccurrences(@NotNull String string, @NotNull String substring) {
return (string.length() - string.replace(substring, "").length()) / substring.length();
}
/**
* Returns the correct separator to use when splitting a string.
*
* @param string string to split
* @param separators separators to check
* @param requiredOccurrences exact amount of occurrences for a separator to be deemed valid
* @return separator to use or {@code null}
* @since v1-alpha1
*/
public static @Nullable String getSeparator(@NotNull String string, @NotNull String @NotNull [] separators, int requiredOccurrences) {
if (string.isBlank() || separators.length == 0 || requiredOccurrences == 0)
return null;
for (String separator : separators)
if (countOccurrences(string, separator) == requiredOccurrences)
return separator;
return null;
}
/**
* Returns the correct separator to use when splitting a string.
*
* @param string string to split
* @param separators separators to check
* @param minimumOccurrences minimum amount of occurrences for a separator to be deemed valid
* @return separator to use or {@code null}
* @since v1-alpha1
*/
public static @Nullable String getSeparator(@NotNull String string, List<String> separators, Integer minimumOccurrences) {
for (String separator : separators)
if (countOccurrences(string, separator) >= minimumOccurrences)
return separator;
return null;
}
/**
* Measures the execution time of a {@link Runnable}.
*
* @param runnable {@link Runnable} to execute
* @return execution time in milliseconds
* @see Runnable
* @since v1-alpha0
*/
public static long measureExecutionTime(@NotNull Runnable runnable) {
long initTime = System.currentTimeMillis();
runnable.run();
return System.currentTimeMillis() - initTime;
}
/**
* Executes a {@link Runnable} and emits {@link ThrowableCatchEvent} if a throwable is caught.
*
* @param runnable {@link Runnable} to execute
* @param identifier some identifier to distinguish {@link Runnable}s
* @since v1-alpha1
*/
public static void executeSafely(@NotNull Runnable runnable, @NotNull String identifier) {
try {
runnable.run();
} catch (Throwable throwable) {
new ThrowableCatchEvent().callEvent(throwable, identifier);
}
}
/**
* Forcefully invokes the garbage collector
* and blocks execution until finished.
* If you want to run it in parallel to your
* program, consider running it in a {@code VirtualThread}.
* <p>
* This method does not guarantee full garbage collection,
* as the JVM only hints the garbage collector to do it's job.
* This is because all garbage collectors are non-deterministic.
*
* @since v1-alpha0
*/
@SuppressWarnings("UnusedAssignment")
public static void invokeGarbageCollector() {
Object object = new Object();
WeakReference<Object> weakReference = new WeakReference<>(object);
object = null;
while(weakReference.get() != null) System.gc();
}
/**
* Ensures that the code is running on the main thread.
*
* @return {@code true} if running on the main thread, {@code false} otherwise
* @since v1-alpha2
*/
public static boolean onMainThread() {
return Thread.currentThread().threadId() == 1;
}
/**
* Returns the {@code Caused by} message usually found when the JVM prints a throwable.
*
* @param throwable {@link Throwable} to use
* @return stack trace header
* @since v1-alpha4
*/
public static @NotNull String getStackTraceHeader(@NotNull Throwable throwable) {
return "Caused by: " + throwable.getClass().getName() + (throwable.getMessage() == null ? "" : ": " + throwable.getMessage());
}
/**
* Converts an array of {@link StackTraceElement}s into a regular string.
*
* @param stacktrace array of {@link StackTraceElement}s to convert
* @param indent if all lines should be indented with a single {@code \t} character, like in regular stack traces
* @return converted stacktrace string
* @since v1-alpha4
*/
public static @NotNull String getStackTraceAsString(@NotNull StackTraceElement @NotNull [] stacktrace, boolean indent) {
StringBuilder output = new StringBuilder();
for (StackTraceElement element : stacktrace) {
if (!output.isEmpty())
output.append("\n");
if (indent)
output.append("\t");
output.append("at ").append(element);
}
return output.toString();
}
/**
* Converts the stacktrace of a throwable into a regular string.
*
* @param throwable throwable to derive the stacktrace from
* @param indent if all lines should be indented with a single {@code \t} character, like in regular stack traces
* @return converted stacktrace string
* @since v1-alpha4
*/
public static @NotNull String getStackTraceAsString(@NotNull Throwable throwable, boolean indent) {
return getStackTraceAsString(throwable.getStackTrace(), indent);
}
}

View file

@ -20,11 +20,11 @@
package de.staropensource.engine.base.utility.information;
import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.type.immutable.ImmutableArrayList;
import org.jetbrains.annotations.NotNull;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.util.Collections;
import java.util.List;
/**
@ -114,7 +114,7 @@ public final class JvmInformation {
* @since v1-alpha0
*/
public static @NotNull List<@NotNull String> getArguments() {
return new ImmutableArrayList<>(ManagementFactory.getRuntimeMXBean().getInputArguments());
return Collections.unmodifiableList(ManagementFactory.getRuntimeMXBean().getInputArguments());
}
/**

View file

@ -0,0 +1,77 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Authors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.utility.misc;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
/**
* Manipulates arrays.
*
* @since v1-alpha9
*/
public final class ArrayUtil {
/**
* Removes the first {@code n} elements
* from the specified array.
* <p>
* If {@code n} is bigger than the
* amount of elements in the
* specified array, an empty array
* will be returned.
*
* @param array array to operate on
* @param n amount to remove
* @return array with the first elements removed
* @since v1-alpha9
*/
public static <T> @Nullable T @NotNull [] removeFirst(@Nullable T @NotNull [] array, int n) {
try {
return Arrays.copyOfRange(array, n, array.length);
} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException exception) {
return Collections.emptyList().toArray(array);
}
}
/**
* Removes the last {@code n} elements
* from the specified array.
* <p>
* If {@code n} is bigger than the
* amount of elements in the
* specified array, an empty array
* will be returned.
*
* @param array array to operate on
* @param n amount to remove
* @return array with the last elements removed
* @since v1-alpha9
*/
public static <T> @Nullable T @NotNull [] removeLast(@Nullable T @NotNull [] array, int n) {
try {
return Arrays.copyOfRange(array, 0, array.length-n);
} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException exception) {
return Collections.emptyList().toArray(array);
}
}
}

View file

@ -17,43 +17,49 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.utility;
package de.staropensource.engine.base.utility.misc;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
/**
* Converts various data types to {@link String}s.
* Converts arrays, arrays and maps to look like
* nicely formatted lists (as {@link String}s).
*
* @since v1-alpha4
* @since v1-alpha9
*/
public final class ListFormatter {
/**
* Creates and initializes an instance of this class.
*
* @since v1-alpha6
* @since v1-alpha9
*/
private ListFormatter() {}
/**
* Converts an array to a {@link String}.
* Converts the specified array to a {@link String}.
* <p>
* For {@code formatArray(array, ", ", " & ")} the
* something like following string will be returned:
* {@code element 1, element 2, element 3 & element 4}
*
* @param array array to convert
* @param itemSeparator string used to separate two items
* @param finalSeparator string used to separate the final two items
* @return formatted string
* @since v1-alpha4
* @since v1-alpha9
*/
public static @NotNull String formatArray(@NotNull Object @NotNull [] array) {
public static @NotNull String formatArray(@NotNull Object @NotNull [] array, @NotNull String itemSeparator, @NotNull String finalSeparator) {
StringBuilder output = new StringBuilder();
for (int index = 0; index < array.length; index++) {
if (!output.isEmpty())
if (index == array.length - 1)
output.append(" & ");
output.append(finalSeparator);
else
output.append(", ");
output.append(itemSeparator);
output.append(array[index]);
}
@ -62,25 +68,50 @@ public final class ListFormatter {
}
/**
* Converts a {@link Set} to a {@link String}.
* Converts the specified array to a {@link String}.
* <p>
* This will produce something like this:
* {@code element 1, element 2, element 3 & element 4}
*
* @param set set to convert
* @param array array to convert
* @return formatted string
* @since v1-alpha4
* @since v1-alpha9
*/
public static @NotNull String formatSet(@NotNull Set<?> set) {
return formatArray(set.toArray());
public static @NotNull String formatArray(@NotNull Object @NotNull [] array) {
return formatArray(array, ", ", " & ");
}
/**
* Converts a {@link List} to a {@link String}.
/**
* Converts the specified array to a {@link String}.
* <p>
* For {@code formatArray(array, ", ", " & ")} the
* something like following string will be returned:
* {@code element 1, element 2, element 3 & element 4}
*
* @param list list to convert
* @param collection collection to convert
* @param itemSeparator string used to separate two items
* @param finalSeparator string used to separate the final two items
* @return formatted string
* @since v1-alpha4
* @since v1-alpha9
*/
public static @NotNull String formatList(@NotNull List<?> list) {
return formatArray(list.toArray());
public static @NotNull String formatCollection(@NotNull Collection<?> collection, @NotNull String itemSeparator, @NotNull String finalSeparator) {
return formatArray(collection.toArray(), itemSeparator, finalSeparator);
}
/**
* Converts the specified {@link Collection} to a {@link String}.
* <p>
* This will produce something like this:
* {@code element 1, element 2, element 3 & element 4}
*
* @param collection collection to convert
* @return formatted string
* @since v1-alpha9
*/
public static @NotNull String formatCollection(@NotNull Collection<?> collection) {
return formatArray(collection.toArray());
}
/**
@ -88,7 +119,7 @@ public final class ListFormatter {
*
* @param map map to convert
* @return formatted string
* @since v1-alpha4
* @since v1-alpha9
*/
public static @NotNull String formatMap(@NotNull Map<?, ?> map) {
StringBuilder output = new StringBuilder();

View file

@ -0,0 +1,165 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Authors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.utility.misc;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.stream.Collectors;
/**
* Contains the most miscellaneous of all miscellaneous methods.
*
* @since v1-alpha9
*/
@SuppressWarnings({ "unused" })
public final class Miscellaneous {
/**
* Creates and initializes an instance of this class.
*
* @since v1-alpha9
*/
private Miscellaneous() {}
/**
* Searches for a value in a {@link Map}.
*
* @param map map to use
* @param value value to search for
* @return all keys matching the specified value
* @since v1-alpha9
*/
public static Set<?> searchForValueInMap(@NotNull Map<?, ?> map, @Nullable Object value) {
return map
.entrySet().stream()
.filter(entry -> Objects.equals(entry.getValue(), value))
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
/**
* Measures the execution time of
* the specified {@link Runnable}.
*
* @param runnable {@link Runnable} to execute
* @return execution time in milliseconds
* @see Runnable
* @since v1-alpha9
*/
public static long measureExecutionTime(@NotNull Runnable runnable) {
long initTime = System.currentTimeMillis();
runnable.run();
return System.currentTimeMillis() - initTime;
}
/**
* Forcefully invokes the garbage collector
* and blocks execution until finished.
* If you want to run it in parallel to your
* program, consider running it in a thread.
* <p>
* This method does not guarantee full garbage collection,
* as the JVM only hints the garbage collector to do it's
* job. All garbage collectors are non-deterministic and
* cannot be invoked by force. And even if this method
* manages to invoke the garbage collector, a full garbage
* collection likely will never be archived. This is because
* the garbage collector will never throw everything into
* the trash. In addition, this method will only return if
* it's {@link WeakReference} becomes null. The garbage
* collector may or may not do more afterwards. This method
* just exists if someone wants to at least try to
* forcefully invoke the garbage collector. If you want
* a somewhat more reliable method, use Java Agents.
*
* @since v1-alpha9
*/
@SuppressWarnings("UnusedAssignment")
public static void invokeGarbageCollector() {
Object object = new Object();
WeakReference<Object> weakReference = new WeakReference<>(object);
object = null;
while(weakReference.get() != null) System.gc();
}
/**
* Returns if the code it is invoked by
* is running on the Java main thread.
*
* @return running on main thread?
* @since v1-alpha9
*/
public static boolean onMainThread() {
return Thread.currentThread().threadId() == 1;
}
/**
* Returns the {@code Caused by} message
* usually found in JVM stack traces.
*
* @param throwable {@link Throwable} to use
* @return {@link Throwable} header
* @since v1-alpha9
*/
public static @NotNull String getThrowableHeader(@NotNull Throwable throwable) {
return "Caused by: " + throwable.getClass().getName() + (throwable.getMessage() == null ? "" : ": " + throwable.getMessage());
}
/**
* Converts an array of {@link StackTraceElement}s into a regular string.
*
* @param stacktrace array of {@link StackTraceElement}s to convert
* @param indent if all lines should be indented with a single tab.
* Enabling this will cause the output of this method
* to mimic the JVM's throwable handling output.
* @return specified stack trace as a String
* @since v1-alpha9
*/
public static @NotNull String stackTraceAsString(@NotNull StackTraceElement @NotNull [] stacktrace, boolean indent) {
StringBuilder output = new StringBuilder();
for (StackTraceElement element : stacktrace) {
if (!output.isEmpty())
output.append("\n");
if (indent)
output.append("\t");
output.append("at ").append(element);
}
return output.toString();
}
/**
* Converts an array of {@link StackTraceElement}s into a regular string.
*
* @param throwable throwable to derive the stacktrace from
* @param indent if all lines should be indented with a single tab.
* Enabling this will cause the output of this method
* to mimic the JVM's throwable handling output.
* @return specified stack trace as a String
* @since v1-alpha9
*/
public static @NotNull String stackTraceAsString(@NotNull Throwable throwable, boolean indent) {
return stackTraceAsString(throwable.getStackTrace(), indent);
}
}

View file

@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.utility;
package de.staropensource.engine.base.utility.misc;
import org.jetbrains.annotations.NotNull;
@ -27,31 +27,36 @@ import java.util.LinkedList;
/**
* Utility class for math operations.
*
* @since v1-alpha2
* @since v1-alpha9
*/
// All mean and double methods have been sourced
// from https://stackoverflow.com/a/4191729, tysm!
@SuppressWarnings({ "unused" })
public final class Math {
public final class NumberUtil {
/**
* Creates and initializes an instance of this class
*
* @since v1-alpha6
* @since v1-alpha9
*/
private Math() {}
private NumberUtil() {}
/**
* Adds padding zeros to a number.
* <p>
* Example:
* {@code padNumbers(505L, 5) = "00505"}
*
* @param number number
* @param length length
* @return the padded number
* @since v1-alpha2
* @since v1-alpha9
*/
public static @NotNull String padNumbers(long number, int length) {
return String.format("%0" + length + "d", number);
}
// -----> Number limiting
/**
* Ensures the integer is inside the
* specified bounds. If not, the
@ -61,10 +66,10 @@ public final class Math {
* @param max maximum value
* @param value value
* @return number in threshold
* @throws IndexOutOfBoundsException when the minimum value is bigger than the maximum value
* @since v1-alpha6
* @throws IndexOutOfBoundsException if the minimum value is bigger than the maximum value
* @since v1-alpha9
*/
public static int boundNumber(int min, int max, int value) throws IndexOutOfBoundsException {
public static int limitNumber(int min, int max, int value) throws IndexOutOfBoundsException {
if (min > max)
throw new IndexOutOfBoundsException();
@ -85,10 +90,10 @@ public final class Math {
* @param max maximum value
* @param value value
* @return number in threshold
* @throws IndexOutOfBoundsException when the minimum value is bigger than the maximum value
* @since v1-alpha6
* @throws IndexOutOfBoundsException if the minimum value is bigger than the maximum value
* @since v1-alpha9
*/
public static float boundNumber(float min, float max, float value) throws IndexOutOfBoundsException {
public static float limitNumber(float min, float max, float value) throws IndexOutOfBoundsException {
if (min > max)
throw new IndexOutOfBoundsException();
@ -109,10 +114,10 @@ public final class Math {
* @param max maximum value
* @param value value
* @return number in threshold
* @throws IndexOutOfBoundsException when the minimum value is bigger than the maximum value
* @since v1-alpha6
* @throws IndexOutOfBoundsException if the minimum value is bigger than the maximum value
* @since v1-alpha9
*/
public static double boundNumber(double min, double max, double value) throws IndexOutOfBoundsException {
public static double limitNumber(double min, double max, double value) throws IndexOutOfBoundsException {
if (min > max)
throw new IndexOutOfBoundsException();
@ -124,14 +129,16 @@ public final class Math {
return value;
}
// -----> Means and medians
/**
* Returns the mean of a collection of numbers.
*
* @param collection collection of {@code double}s
* @return mean
* @since v1-alpha2
* @since v1-alpha9
*/
public static double getMeanDouble(@NotNull Collection<@NotNull Double> collection) {
public static double calculateMeanDouble(@NotNull Collection<@NotNull Double> collection) {
double sum = 0;
for (double number : collection)
@ -145,9 +152,9 @@ public final class Math {
*
* @param collection collection of {@code float}s
* @return mean
* @since v1-alpha2
* @since v1-alpha9
*/
public static double getMeanFloat(@NotNull Collection<@NotNull Float> collection) {
public static double calculateMeanFloat(@NotNull Collection<@NotNull Float> collection) {
double sum = 0;
for (float number : collection)
@ -161,9 +168,9 @@ public final class Math {
*
* @param collection collection of {@code long}s
* @return mean
* @since v1-alpha2
* @since v1-alpha9
*/
public static double getMeanLong(@NotNull Collection<@NotNull Long> collection) {
public static double calculateMeanLong(@NotNull Collection<@NotNull Long> collection) {
double sum = 0;
for (long number : collection)
@ -177,9 +184,9 @@ public final class Math {
*
* @param collection collection of {@code int}s
* @return mean
* @since v1-alpha2
* @since v1-alpha9
*/
public static double getMeanInt(@NotNull Collection<@NotNull Integer> collection) {
public static double calculateMeanInt(@NotNull Collection<@NotNull Integer> collection) {
double sum = 0;
for (int number : collection)
@ -193,9 +200,9 @@ public final class Math {
*
* @param list linked list of {@code double}s
* @return median
* @since v1-alpha2
* @since v1-alpha9
*/
public static double getMedianDouble(@NotNull LinkedList<@NotNull Double> list) {
public static double calculateMedianDouble(@NotNull LinkedList<@NotNull Double> list) {
int middle = list.size() / 2;
if (list.size() % 2 == 1)
return list.get(middle);
@ -208,9 +215,9 @@ public final class Math {
*
* @param list linked list of {@code float}s
* @return median
* @since v1-alpha2
* @since v1-alpha9
*/
public static double getMedianFloat(@NotNull LinkedList<@NotNull Float> list) {
public static double calculateMedianFloat(@NotNull LinkedList<@NotNull Float> list) {
int middle = list.size() / 2;
if (list.size() % 2 == 1)
return list.get(middle);
@ -223,9 +230,9 @@ public final class Math {
*
* @param list linked list of {@code long}s
* @return median
* @since v1-alpha2
* @since v1-alpha9
*/
public static double getMedianLong(@NotNull LinkedList<@NotNull Long> list) {
public static double calculateMedianLong(@NotNull LinkedList<@NotNull Long> list) {
int middle = list.size() / 2;
if (list.size() % 2 == 1)
return list.get(middle);
@ -238,9 +245,9 @@ public final class Math {
*
* @param list linked list of {@code int}s
* @return median
* @since v1-alpha2
* @since v1-alpha9
*/
public static double getMedianInt(@NotNull LinkedList<@NotNull Integer> list) {
public static double calculateMedianInt(@NotNull LinkedList<@NotNull Integer> list) {
int middle = list.size() / 2;
if (list.size() % 2 == 1)
return list.get(middle);

View file

@ -0,0 +1,85 @@
/*
* STAROPENSOURCE ENGINE SOURCE FILE
* Copyright (c) 2024 The StarOpenSource Engine Authors
* Licensed under the GNU Affero General Public License v3
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.utility.misc;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Manipulates strings and characters.
*
* @since v1-alpha9
*/
public final class StringUtil {
/**
* Counts the number of occurrences of the specified substring inside the specified string.
*
* @param string string to search in
* @param substring substring to count occurrences for
* @return number of times the specified substring was found inside the specified string
* @since v1-alpha9
*/
public static long count(@NotNull String string, @NotNull String substring) {
return (string.length() - string.replace(substring, "").length()) / substring.length();
}
/**
* Searches for the specified separators
* in the specified string and returns
* the first separator which matches the
* specified amount of required occurrences.
*
* @param string string to operate on
* @param separators separators to check for
* @param requiredOccurrences exact amount of occurrences for a separator to be deemed valid
* @return separator to use or {@code null}
* @since v1-alpha9
*/
public static @Nullable String getSeparatorRequired(@NotNull String string, @NotNull String @NotNull [] separators, int requiredOccurrences) {
if (string.isBlank() || separators.length == 0 || requiredOccurrences == 0)
return null;
for (String separator : separators)
if (count(string, separator) == requiredOccurrences)
return separator;
return null;
}
/**
* Searches for the specified separators
* in the specified string and returns
* the first separator which matches the
* specified amount of minimum occurrences.
*
* @param string string to operate on
* @param separators separators to check for
* @param minimumOccurrences minimum amount of occurrences for a separator to be deemed valid
* @return separator to use or {@code null}
* @since v1-alpha9
*/
public static @Nullable String getSeparatorMinimum(@NotNull String string, @NotNull String @NotNull [] separators, int minimumOccurrences) {
for (String separator : separators)
if (count(string, separator) >= minimumOccurrences)
return separator;
return null;
}
}

View file

@ -17,39 +17,37 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.type;
package de.staropensource.engine.base.utility.misc;
import de.staropensource.engine.base.type.Tristate;
import org.jetbrains.annotations.Range;
/**
* Represents various file types.
* Converts various data types into other data types.
*
* @since v1-alpha8
* @since v1-alpha9
*/
public enum FileType {
public final class TypeConversion {
/**
* The path does not exist.
* Converts a boolean into an integer.
*
* @since v1-alpha8
* @param bool boolean to convert
* @return converted integer
* @since v1-alpha9
*/
VOID,
@Range(from = 0, to = 1)
public static int booleanToInteger(boolean bool) {
return bool ? 1 : 0;
}
/**
* It's a regular file.
* Converts an integer into a {@link Tristate} and then into a boolean.
*
* @since v1-alpha8
* @param integer integer to convert
* @return booleanized integer
* @since v1-alpha9
*/
FILE,
/**
* It's a directory containing files.
*
* @since v1-alpha8
*/
DIRECTORY,
/**
* The file type is unknown to the sos!engine.
*
* @since v1-alpha8
*/
UNKNOWN
public static boolean integerToBoolean(@Range(from = 0, to = 1) int integer) throws IndexOutOfBoundsException {
return integer != 0;
}
}

View file

@ -18,8 +18,8 @@
*/
/**
* Immutable variations of regular Java data types.
* Miscellaneous utility classes.
*
* @since v1-alpha1
* @since v1-alpha9
*/
package de.staropensource.engine.base.type.immutable;
package de.staropensource.engine.base.utility.misc;

View file

@ -20,7 +20,7 @@
/**
* Provides (utility) classes specifically made for one task.
*
* @see de.staropensource.engine.base.utility.Miscellaneous
* @see de.staropensource.engine.base.utility.misc.Miscellaneous
* @since v1-alpha0
*/
package de.staropensource.engine.base.utility;

View file

@ -29,11 +29,11 @@ module sosengine.base {
exports de.staropensource.engine.base.implementation.logging;
exports de.staropensource.engine.base.reflection;
exports de.staropensource.engine.base.type;
exports de.staropensource.engine.base.type.immutable;
exports de.staropensource.engine.base.type.logging;
exports de.staropensource.engine.base.type.reflection;
exports de.staropensource.engine.base.type.vector;
exports de.staropensource.engine.base.utility;
exports de.staropensource.engine.base.utility.misc;
// Reflection access
opens de.staropensource.engine.base;
@ -52,9 +52,9 @@ module sosengine.base {
opens de.staropensource.engine.base.implementation.logging;
opens de.staropensource.engine.base.reflection;
opens de.staropensource.engine.base.type;
opens de.staropensource.engine.base.type.immutable;
opens de.staropensource.engine.base.type.logging;
opens de.staropensource.engine.base.type.reflection;
opens de.staropensource.engine.base.type.vector;
opens de.staropensource.engine.base.utility;
opens de.staropensource.engine.base.utility.misc;
}

View file

@ -21,11 +21,9 @@ package de.staropensource.engine.base.srctests.utility;
import de.staropensource.engine.base.EngineConfiguration;
import de.staropensource.engine.base.annotation.EventListener;
import de.staropensource.engine.base.event.ThrowableCatchEvent;
import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.testing.TestBase;
import de.staropensource.engine.base.utility.Math;
import de.staropensource.engine.base.utility.Miscellaneous;
import de.staropensource.engine.base.utility.misc.NumberUtil;
import de.staropensource.engine.base.utility.misc.Miscellaneous;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@ -66,7 +64,7 @@ public class MiscellaneousTest extends TestBase {
if (performMethodCalls("testPadNumbers", number, length, expected))
return;
String result = Math.padNumbers(number, length);
String result = NumberUtil.padNumbers(number, length);
assertEquals(expected, result, "Result \"" + result + "\" does not match expected output \"" + expected + "\"");
}
@ -98,7 +96,7 @@ public class MiscellaneousTest extends TestBase {
*/
@Test
@DisplayName("getMapValues")
void testGetMapValues() {
void testSearchForValueInMap() {
if (performMethodCalls("testGetMapValues"))
return;
@ -109,28 +107,13 @@ public class MiscellaneousTest extends TestBase {
testMap.put("keylast", "this is the last value");
testMap.put("keylast2", "this is the last value");
Set<?> output = Miscellaneous.getMapValues(testMap, "this value exists twice");
Set<?> output = Miscellaneous.searchForValueInMap(testMap, "this value exists twice");
assertTrue(output.contains("keytwo"), "Map key \"keytwo\" not found in output Set");
assertTrue(output.contains("keydrei"), "Map key \"keydrei\" not found in output Set");
assertEquals(2, output.size(), "There are more or less than two keys in the output Set");
}
/**
* Tests the method {@code executeSafely}.
*/
@Test
@DisplayName("executeSafely (test 0)")
void testExecuteSafely0() {
if (performMethodCalls("testExecuteSafely0"))
return;
throwableCaught = false;
Miscellaneous.executeSafely(() -> Logger.info("You can safely ignore this message (this comes from MiscellaneousTest#testExecuteSafely0)"), "MiscellaneousTest#testExecuteSafely0");
assertFalse(throwableCaught, "Event was triggered");
}
/**
* Tests the method {@code executeSafely}.
*/

View file

@ -23,7 +23,6 @@ import de.staropensource.engine.base.Engine;
import de.staropensource.engine.base.EngineConfiguration;
import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.type.logging.LogLevel;
import de.staropensource.engine.base.utility.Miscellaneous;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Marker;
import org.slf4j.event.Level;

View file

@ -86,6 +86,9 @@ application {
// reflective sclasspath scanning is disabled.
"-Dsosengine.base.initialIncludeSubsystemClasses=de.staropensource.engine.ansi.AnsiSubsystem,de.staropensource.engine.slf4j_compat.Slf4jCompatSubsystem,de.staropensource.engine.windowing.glfw.GlfwSubsystem",
// Force rendering platform
"-Dsosengine.rendering.initialPlatform=" + (project.hasProperty("renderingPlatform") ? project.property("renderingPlatform") as String : "any"),
// Force Jansi to write escape sequences
"-Djansi.mode=force",
]
@ -129,6 +132,7 @@ tasks.register('runNativeImage', Exec) {
"-Dsosengine.base.logForceStandardOutput=true",
"-Dsosengine.base.initialForceDisableClasspathScanning=true",
"-Dsosengine.base.initialIncludeSubsystemClasses=de.staropensource.engine.ansi.AnsiSubsystem,de.staropensource.engine.slf4j_compat.Slf4jCompatSubsystem,de.staropensource.engine.windowing.glfw.GlfwSubsystem",
"-Dsosengine.rendering.initialPlatform=" + (project.hasProperty("renderingPlatform") ? project.property("renderingPlatform") as String : "any"),
"-Djansi.mode=force",
)
executable("build/bin/sosengine-testapp")

View file

@ -25,7 +25,7 @@ import de.staropensource.engine.base.implementable.EventListenerCode;
import de.staropensource.engine.base.implementable.helper.EventHelper;
import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.type.vector.Vec2i;
import de.staropensource.engine.base.utility.Miscellaneous;
import de.staropensource.engine.base.utility.misc.Miscellaneous;
import de.staropensource.engine.rendering.RenderingSubsystem;
import de.staropensource.engine.rendering.event.InputEvent;
import de.staropensource.engine.rendering.type.Window;
@ -135,8 +135,10 @@ public final class Main {
return;
}
if (window == null)
if (window == null) {
Logger.crash("'window' is null");
return;
}
// Render loop
LinkedHashMap<@NotNull Window, @NotNull Throwable> renderLoopFailures = RenderingSubsystem
@ -146,6 +148,7 @@ public final class Main {
Engine.getInstance().shutdown();
});
// Print render loop failures
StringBuilder message = new StringBuilder();
message.append("Render loop failed on some windows:\n");
@ -155,9 +158,9 @@ public final class Main {
.append("-> ")
.append(window)
.append(": ")
.append(Miscellaneous.getStackTraceHeader(renderLoopFailures.get(windowFailed)))
.append(Miscellaneous.getThrowableHeader(renderLoopFailures.get(windowFailed)))
.append("\n")
.append(Miscellaneous.getStackTraceAsString(renderLoopFailures.get(windowFailed), true))
.append(Miscellaneous.stackTraceAsString(renderLoopFailures.get(windowFailed), true))
.append("\n");
Logger.crash(message.toString());