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 #### Parallelism
Use the `jobs` property to control how many jobs will get executed simultaneously. Use the `jobs` property to control how many jobs will get executed simultaneously.
On Linux, specify `-Pjobs=$(nproc)`. Defaults to `8`. 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 #### JVM Home
You can use the `graalHome` property to specify the `$JAVA_HOME` of your local GraalVM installation. 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. 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.logging.backend.async.LoggingThread;
import de.staropensource.engine.base.type.DependencyVector; import de.staropensource.engine.base.type.DependencyVector;
import de.staropensource.engine.base.type.EngineState; 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.DependencyResolver;
import de.staropensource.engine.base.utility.FileAccess; 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.PlaceholderEngine;
import de.staropensource.engine.base.utility.information.EngineInformation; import de.staropensource.engine.base.utility.information.EngineInformation;
import de.staropensource.engine.base.utility.information.JvmInformation; import de.staropensource.engine.base.utility.information.JvmInformation;
@ -114,7 +113,7 @@ public final class Engine extends SubsystemClass {
* @since v1-alpha1 * @since v1-alpha1
*/ */
@Getter @Getter
private @NotNull ImmutableLinkedList<@NotNull DependencySubsystemVector> subsystems = new ImmutableLinkedList<>(); private @NotNull List<@NotNull DependencySubsystemVector> subsystems = Collections.emptyList();
/** /**
* Contains the engine's shutdown handler. * Contains the engine's shutdown handler.
@ -291,8 +290,8 @@ public final class Engine extends SubsystemClass {
new Engine(); new Engine();
} catch (RuntimeException exception) { } catch (RuntimeException exception) {
Logger.error("Engine initialization failed"); Logger.error("Engine initialization failed");
Logger.error(Miscellaneous.getStackTraceHeader(exception.getCause())); Logger.error(Miscellaneous.getThrowableHeader(exception.getCause()));
for (String line : Miscellaneous.getStackTraceAsString(exception.getCause(), true).split("\n")) for (String line : Miscellaneous.stackTraceAsString(exception.getCause(), true).split("\n"))
Logger.error(line); Logger.error(line);
throw new RuntimeException("Engine initialization failed", exception.getCause()); throw new RuntimeException("Engine initialization failed", exception.getCause());
@ -366,7 +365,6 @@ public final class Engine extends SubsystemClass {
EventHelper.cacheEvent(EngineSoftCrashEvent.class); EventHelper.cacheEvent(EngineSoftCrashEvent.class);
EventHelper.cacheEvent(InternalEngineShutdownEvent.class); EventHelper.cacheEvent(InternalEngineShutdownEvent.class);
EventHelper.cacheEvent(LogEvent.class); EventHelper.cacheEvent(LogEvent.class);
EventHelper.cacheEvent(ThrowableCatchEvent.class);
} }
/** /**
@ -401,7 +399,7 @@ public final class Engine extends SubsystemClass {
} }
// Update 'subsystems' // Update 'subsystems'
subsystems = new ImmutableLinkedList<>(subsystemsMutable); subsystems = Collections.unmodifiableList(subsystemsMutable);
} }
/** /**
@ -488,7 +486,7 @@ public final class Engine extends SubsystemClass {
} }
// Update 'subsystems' // Update 'subsystems'
subsystems = new ImmutableLinkedList<>(order); subsystems = Collections.unmodifiableList(order);
} }
/** /**

View file

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

View file

@ -20,7 +20,6 @@
package de.staropensource.engine.base.annotation; package de.staropensource.engine.base.annotation;
import de.staropensource.engine.base.implementable.Event; import de.staropensource.engine.base.implementable.Event;
import de.staropensource.engine.base.type.EventPriority;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.lang.annotation.*; import java.lang.annotation.*;
@ -48,8 +47,8 @@ public @interface EventListener {
* Specifies the priority of the event. * Specifies the priority of the event.
* *
* @return event priority * @return event priority
* @see EventPriority * @see Event.Priority
* @since v1-alpha0 * @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; package de.staropensource.engine.base.exception.reflection;
import de.staropensource.engine.base.type.reflection.ClassType; 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; import org.jetbrains.annotations.NotNull;
/** /**

View file

@ -19,6 +19,7 @@
package de.staropensource.engine.base.implementable; package de.staropensource.engine.base.implementable;
import de.staropensource.engine.base.annotation.EventListener;
import de.staropensource.engine.base.implementable.helper.EventHelper; import de.staropensource.engine.base.implementable.helper.EventHelper;
/** /**
@ -34,4 +35,76 @@ public interface Event {
* @since v1-alpha0 * @since v1-alpha0
*/ */
void callEvent(); 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; package de.staropensource.engine.base.implementable;
import de.staropensource.engine.base.implementable.helper.EventHelper; import de.staropensource.engine.base.implementable.helper.EventHelper;
import de.staropensource.engine.base.type.EventPriority;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
@ -39,7 +38,7 @@ public abstract class EventListenerCode {
* *
* @since v1-alpha5 * @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. * 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.internal.implementation.EventListenerMethod;
import de.staropensource.engine.base.logging.Logger; import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.type.EventPriority; import de.staropensource.engine.base.utility.misc.ListFormatter;
import de.staropensource.engine.base.utility.ListFormatter;
import lombok.Getter; import lombok.Getter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -78,7 +77,7 @@ public final class EventHelper {
* @see EngineInternals#getReflectiveClasspathScanning() * @see EngineInternals#getReflectiveClasspathScanning()
* @since v1-alpha5 * @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()) if (EngineInternals.getInstance().getReflectiveClasspathScanning())
return; return;
@ -112,7 +111,7 @@ public final class EventHelper {
* @since v1-alpha5 * @since v1-alpha5
*/ */
public static void registerEvent(@NotNull Class<? extends Event> event, @NotNull EventListenerCode eventListener) { 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.implementable.VersioningSystem;
import de.staropensource.engine.base.exception.versioning.IncompatibleVersioningSystemException; import de.staropensource.engine.base.exception.versioning.IncompatibleVersioningSystemException;
import de.staropensource.engine.base.exception.versioning.InvalidVersionStringException; 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 lombok.Getter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range; import org.jetbrains.annotations.Range;
@ -98,7 +98,7 @@ public final class FourNumberVersioningSystem implements VersioningSystem {
*/ */
public FourNumberVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException { public FourNumberVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException {
String[] separatorList = new String[]{ ".", "-" }; 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 // Escape separator or throw error if invalid
switch (separator) { 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.implementable.VersioningSystem;
import de.staropensource.engine.base.exception.versioning.IncompatibleVersioningSystemException; import de.staropensource.engine.base.exception.versioning.IncompatibleVersioningSystemException;
import de.staropensource.engine.base.exception.versioning.InvalidVersionStringException; 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 lombok.Getter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -117,7 +117,7 @@ public final class SemanticVersioningSystem implements VersioningSystem {
*/ */
public SemanticVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException { public SemanticVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException {
String[] separatorList = new String[]{ "." }; 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 // Escape separator or throw error if invalid
switch (separator) { 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.implementable.VersioningSystem;
import de.staropensource.engine.base.exception.versioning.IncompatibleVersioningSystemException; import de.staropensource.engine.base.exception.versioning.IncompatibleVersioningSystemException;
import de.staropensource.engine.base.exception.versioning.InvalidVersionStringException; 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 lombok.Getter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range; import org.jetbrains.annotations.Range;
@ -86,7 +86,7 @@ public final class ThreeNumberVersioningSystem implements VersioningSystem {
*/ */
public ThreeNumberVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException { public ThreeNumberVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException {
String[] separatorList = new String[]{ ".", "-" }; 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 // Escape separator or throw error if invalid
switch (separator) { 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.implementable.VersioningSystem;
import de.staropensource.engine.base.exception.versioning.IncompatibleVersioningSystemException; import de.staropensource.engine.base.exception.versioning.IncompatibleVersioningSystemException;
import de.staropensource.engine.base.exception.versioning.InvalidVersionStringException; 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 lombok.Getter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range; import org.jetbrains.annotations.Range;
@ -74,7 +74,7 @@ public final class TwoNumberVersioningSystem implements VersioningSystem {
*/ */
public TwoNumberVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException { public TwoNumberVersioningSystem(@NotNull String versionString) throws InvalidVersionStringException {
String[] separatorList = new String[]{ ".", "-" }; 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 // Escape separator or throw error if invalid
switch (separator) { switch (separator) {

View file

@ -20,7 +20,7 @@
package de.staropensource.engine.base.internal.implementation.placeholder; package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.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 org.jetbrains.annotations.NotNull;
import java.util.Calendar; import java.util.Calendar;
@ -43,6 +43,6 @@ public final class DateDay implements Placeholder {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public @NotNull String replace(@NotNull String text) { 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; package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.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 org.jetbrains.annotations.NotNull;
import java.util.Calendar; import java.util.Calendar;
@ -43,6 +43,6 @@ public final class DateMonth implements Placeholder {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public @NotNull String replace(@NotNull String text) { 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; package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.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 org.jetbrains.annotations.NotNull;
import java.util.Calendar; import java.util.Calendar;
@ -43,6 +43,6 @@ public final class DateYear implements Placeholder {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public @NotNull String replace(@NotNull String text) { 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; package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.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 org.jetbrains.annotations.NotNull;
/** /**
@ -42,6 +42,6 @@ public final class TimeEpoch implements Placeholder {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public @NotNull String replace(@NotNull String text) { 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; package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.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 org.jetbrains.annotations.NotNull;
import java.util.Calendar; import java.util.Calendar;
@ -43,6 +43,6 @@ public final class TimeHour implements Placeholder {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public @NotNull String replace(@NotNull String text) { 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; package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.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 org.jetbrains.annotations.NotNull;
import java.util.Calendar; import java.util.Calendar;
@ -43,6 +43,6 @@ public final class TimeMinute implements Placeholder {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public @NotNull String replace(@NotNull String text) { 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; package de.staropensource.engine.base.internal.implementation.placeholder;
import de.staropensource.engine.base.implementable.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 org.jetbrains.annotations.NotNull;
import java.util.Calendar; import java.util.Calendar;
@ -43,6 +43,6 @@ public final class TimeSecond implements Placeholder {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public @NotNull String replace(@NotNull String text) { 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; package de.staropensource.engine.base.logging;
import de.staropensource.engine.base.EngineConfiguration;
import de.staropensource.engine.base.implementable.LoggingAdapter; import de.staropensource.engine.base.implementable.LoggingAdapter;
import de.staropensource.engine.base.implementation.logging.PlainLoggingAdapter; 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.CrashHandler;
import de.staropensource.engine.base.logging.backend.Filterer; import de.staropensource.engine.base.logging.backend.Filterer;
import de.staropensource.engine.base.logging.backend.Processor; import de.staropensource.engine.base.logging.backend.Processor;
import de.staropensource.engine.base.logging.backend.async.LoggingQueue; 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 de.staropensource.engine.base.type.logging.LogLevel;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -35,8 +32,6 @@ import org.intellij.lang.annotations.RegExp;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List;
/** /**
* The frontend class for sos!engine's logging system. * 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.EngineInternals;
import de.staropensource.engine.base.logging.Logger; import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.type.logging.LogLevel; 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.Miscellaneous; import de.staropensource.engine.base.utility.misc.Miscellaneous;
import de.staropensource.engine.base.utility.information.EngineInformation; import de.staropensource.engine.base.utility.information.EngineInformation;
import de.staropensource.engine.base.utility.information.JvmInformation; import de.staropensource.engine.base.utility.information.JvmInformation;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -110,9 +110,9 @@ public final class CrashHandler {
else else
output output
.append("\n") .append("\n")
.append(Miscellaneous.getStackTraceHeader(throwable)) .append(Miscellaneous.getThrowableHeader(throwable))
.append("\n") .append("\n")
.append(Miscellaneous.getStackTraceAsString(throwable, true)) .append(Miscellaneous.stackTraceAsString(throwable, true))
.append("\n"); .append("\n");
output.append("\nMessage: \n") output.append("\nMessage: \n")
@ -123,23 +123,23 @@ public final class CrashHandler {
output output
.append("---- Environment ----") .append("---- Environment ----")
.append("\nTime and date: ") .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(".")
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.MONTH), 2)) .append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.MONTH), 2))
.append(".") .append(".")
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.YEAR), 4)) .append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.YEAR), 4))
.append(" ") .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(":")
.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(":")
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.SECOND), 2)) .append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.SECOND), 2))
.append(" [") .append(" [")
.append(TimeZone.getDefault().getDisplayName(false, TimeZone.SHORT, Locale.US)) .append(TimeZone.getDefault().getDisplayName(false, TimeZone.SHORT, Locale.US))
.append("]") .append("]")
.append("\nUNIX Epoch: ") .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("\nOperating system: ")
.append(System.getProperty("os.name")) .append(System.getProperty("os.name"))
@ -293,7 +293,7 @@ public final class CrashHandler {
.append(thread.isDaemon()) .append(thread.isDaemon())
.append("):") .append("):")
.append("\n") .append("\n")
.append(Miscellaneous.getStackTraceAsString(stacktraces.get(thread), false)) .append(Miscellaneous.stackTraceAsString(stacktraces.get(thread), false))
.append("\n"); .append("\n");
} }
output.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.Logger;
import de.staropensource.engine.base.logging.backend.async.LoggingQueue; import de.staropensource.engine.base.logging.backend.async.LoggingQueue;
import de.staropensource.engine.base.type.logging.LogLevel; 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.PlaceholderEngine;
import de.staropensource.engine.base.utility.information.JvmInformation; import de.staropensource.engine.base.utility.information.JvmInformation;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -213,11 +213,11 @@ public final class Processor {
private static void time(@NotNull StringBuilder builder) { private static void time(@NotNull StringBuilder builder) {
if (isFeatureEnabled("time")) if (isFeatureEnabled("time"))
builder 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(":")
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.MINUTE), 2)) .append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.MINUTE), 2))
.append(":") .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) { private static void date(@NotNull StringBuilder builder) {
if (isFeatureEnabled("date")) if (isFeatureEnabled("date"))
builder 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(".")
.append(Math.padNumbers(Calendar.getInstance().get(Calendar.MONTH), 2)) .append(NumberUtil.padNumbers(Calendar.getInstance().get(Calendar.MONTH), 2))
.append(".") .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.internal.type.QueuedLogCall;
import de.staropensource.engine.base.logging.backend.Processor; 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 de.staropensource.engine.base.type.logging.LogLevel;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -67,8 +66,8 @@ public final class LoggingQueue {
* @since v1-alpha8 * @since v1-alpha8
*/ */
public static void flush() { public static void flush() {
// Get copy of and clear queue // Get copy of and clear the queue
List<@NotNull QueuedLogCall> queue = new ImmutableArrayList<>(LoggingQueue.queue); List<@NotNull QueuedLogCall> queue = new ArrayList<>(LoggingQueue.queue);
LoggingQueue.queue.clear(); LoggingQueue.queue.clear();
for (QueuedLogCall queuedCall : queue) for (QueuedLogCall queuedCall : queue)

View file

@ -20,7 +20,7 @@
package de.staropensource.engine.base.type; package de.staropensource.engine.base.type;
import de.staropensource.engine.base.EngineConfiguration; 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.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.SneakyThrows; import lombok.SneakyThrows;
@ -42,7 +42,7 @@ import java.util.Locale;
@Getter @Getter
@Setter @Setter
@SuppressWarnings({ "JavadocDeclaration" }) @SuppressWarnings({ "JavadocDeclaration" })
public final class Color { public class Color {
/** /**
* Contains the red color value. * Contains the red color value.
* *
@ -118,10 +118,10 @@ public final class Color {
* @since v1-alpha6 * @since v1-alpha6
*/ */
private Color(int red, int green, int blue, int alpha) { private Color(int red, int green, int blue, int alpha) {
this.red = Math.boundNumber(0, 255, red); this.red = NumberUtil.limitNumber(0, 255, red);
this.green = Math.boundNumber(0, 255, green); this.green = NumberUtil.limitNumber(0, 255, green);
this.blue = Math.boundNumber(0, 255, blue); this.blue = NumberUtil.limitNumber(0, 255, blue);
this.alpha = Math.boundNumber(0, 255, alpha); 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 { public enum Tristate {
/** /**
* An unset tristate. * Defines an unset state.
* *
* @since v1-alpha1 * @since v1-alpha1
*/ */
UNSET, UNSET,
/** /**
* A true tristate. * Defines a true state.
* *
* @since v1-alpha1 * @since v1-alpha1
*/ */
TRUE, TRUE,
/** /**
* A false tristate. * Defines a false state.
* *
* @since v1-alpha1 * @since v1-alpha1
*/ */
FALSE; FALSE;
/** /**
* Converts the {@link Boolean} into a {@link Tristate}. * Converts the specified {@link Boolean} into a {@link Tristate}.
* *
* @param bool boolean to convert * @param bool boolean to convert
* @return tristated boolean * @return {@link Tristate} representation of the specified boolean
* @since v1-alpha5 * @since v1-alpha9
*/ */
public static @NotNull Tristate toTristate(boolean bool) { public static @NotNull Tristate toTristate(boolean bool) {
if (bool) return Tristate.TRUE; 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. * Make sure to check for {@link #UNSET} first.
* *
* @return booleanized {@link Tristate} * @return trimmed boolean representation of this {@link Tristate}
* @throws TristateConversionException when encountering {@link #UNSET} * @throws TristateConversionException on encountering {@link #UNSET}
* @since v1-alpha2 * @since v1-alpha9
*/ */
public boolean toBoolean() { public boolean toBoolean() {
return switch (this) { return switch (this) {
@ -76,4 +92,19 @@ public enum Tristate {
case FALSE -> false; 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; 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 * @see StarOpenSourceVersioningSystem
* @since v1-alpha0 * @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.Engine;
import de.staropensource.engine.base.logging.Logger; import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.type.EngineState; 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 lombok.Getter;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -190,7 +190,7 @@ public final class FileAccess {
if (Files.exists(path)) if (Files.exists(path))
Logger.error("Deleting file or directory \"" + path + "\" failed"); Logger.error("Deleting file or directory \"" + path + "\" failed");
} catch (Exception exception) { } 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 * @return file type
* @since v1-alpha8 * @since v1-alpha8
*/ */
public @NotNull FileType getType() { public @NotNull FileAccess.Type getType() {
if (!exists()) if (!exists())
return FileType.VOID; return Type.VOID;
else if (Files.isRegularFile(path)) else if (Files.isRegularFile(path))
return FileType.FILE; return Type.FILE;
else if (Files.isDirectory(path)) else if (Files.isDirectory(path))
return FileType.DIRECTORY; return Type.DIRECTORY;
else else
return FileType.UNKNOWN; return Type.UNKNOWN;
} }
/** /**
@ -309,7 +309,7 @@ public final class FileAccess {
* @since v1-alpha8 * @since v1-alpha8
*/ */
public @NotNull String @NotNull [] listContents() throws UnsupportedOperationException, IOException { 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"); throw new UnsupportedOperationException("The file \"" + path + "\" is not a directory");
String[] list = file.list(); String[] list = file.list();
@ -661,7 +661,7 @@ public final class FileAccess {
* Returns the contents of this file. * Returns the contents of this file.
* <p> * <p>
* Returns an empty array if this file * 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 * @return file contents in bytes
* @throws IOException on an IO error * @throws IOException on an IO error
@ -669,7 +669,7 @@ public final class FileAccess {
* @since v1-alpha8 * @since v1-alpha8
*/ */
public byte @NotNull [] readBytes() throws IOException, OutOfMemoryError { public byte @NotNull [] readBytes() throws IOException, OutOfMemoryError {
if (getType() != FileType.FILE) if (getType() != Type.FILE)
return new byte[0]; return new byte[0];
Logger.diag("Reading file \"" + path + "\" (bytes)"); Logger.diag("Reading file \"" + path + "\" (bytes)");
@ -680,7 +680,7 @@ public final class FileAccess {
* Returns the contents of this file. * Returns the contents of this file.
* <p> * <p>
* Returns an empty list if this file * 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 * @return file contents in bytes
* @throws IOException on an IO error * @throws IOException on an IO error
@ -688,7 +688,7 @@ public final class FileAccess {
* @since v1-alpha8 * @since v1-alpha8
*/ */
public @NotNull List<@NotNull String> readLines() throws IOException, OutOfMemoryError { public @NotNull List<@NotNull String> readLines() throws IOException, OutOfMemoryError {
if (getType() != FileType.FILE) if (getType() != Type.FILE)
return new ArrayList<>(); return new ArrayList<>();
Logger.diag("Reading file \"" + path + "\" (lines)"); Logger.diag("Reading file \"" + path + "\" (lines)");
@ -701,7 +701,7 @@ public final class FileAccess {
* {@link StandardCharsets#UTF_8} character set. * {@link StandardCharsets#UTF_8} character set.
* <p> * <p>
* Returns an empty string if this file * 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 * @return file contents as a string
* @throws IOException on an IO error * @throws IOException on an IO error
@ -716,7 +716,7 @@ public final class FileAccess {
* Returns the contents of this file. * Returns the contents of this file.
* <p> * <p>
* Returns an empty string if this file * 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 * @param charset charset to decode the bytes with
* @return file contents as a string * @return file contents as a string
@ -725,7 +725,7 @@ public final class FileAccess {
* @since v1-alpha8 * @since v1-alpha8
*/ */
public @NotNull String readContent(@NotNull Charset charset) throws IOException, OutOfMemoryError { public @NotNull String readContent(@NotNull Charset charset) throws IOException, OutOfMemoryError {
if (getType() != FileType.FILE) if (getType() != Type.FILE)
return ""; return "";
Logger.diag("Reading file \"" + path + "\" (string)"); Logger.diag("Reading file \"" + path + "\" (string)");
@ -739,15 +739,15 @@ public final class FileAccess {
* *
* @param bytes bytes to write * @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} * @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 * @throws IOException on an IO error
* @return this instance * @return this instance
*/ */
public @NotNull FileAccess writeBytes(byte @NotNull [] bytes, boolean async) throws UnsupportedOperationException, IOException { public @NotNull FileAccess writeBytes(byte @NotNull [] bytes, boolean async) throws UnsupportedOperationException, IOException {
if (getType() == FileType.VOID) if (getType() == Type.VOID)
createFile(); createFile();
else if (getType() != FileType.FILE) else if (getType() != Type.FILE)
throw new UnsupportedOperationException("File \"" + path + "\" is not of type FileType.VOID or FileType.FILE"); throw new UnsupportedOperationException("File \"" + path + "\" is not of type Type.VOID or Type.FILE");
createFile(); createFile();
Logger.diag("Writing file \"" + path + "\" (bytes, " + (async ? "async" : "dsync") + ")"); Logger.diag("Writing file \"" + path + "\" (bytes, " + (async ? "async" : "dsync") + ")");
@ -762,7 +762,7 @@ public final class FileAccess {
* *
* @param string string to write * @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} * @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 * @throws IOException on an IO error
* @return this instance * @return this instance
*/ */
@ -776,15 +776,15 @@ public final class FileAccess {
* @param string string to write * @param string string to write
* @param charset charset to encode the string in * @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} * @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 * @throws IOException on an IO error
* @return this instance * @return this instance
*/ */
public @NotNull FileAccess writeString(@NotNull String string, @NotNull Charset charset, boolean async) throws UnsupportedOperationException, IOException { public @NotNull FileAccess writeString(@NotNull String string, @NotNull Charset charset, boolean async) throws UnsupportedOperationException, IOException {
if (getType() == FileType.VOID) if (getType() == Type.VOID)
createFile(); createFile();
else if (getType() != FileType.FILE) else if (getType() != Type.FILE)
throw new UnsupportedOperationException("File \"" + path + "\" is not of type FileType.VOID or FileType.FILE"); throw new UnsupportedOperationException("File \"" + path + "\" is not of type Type.VOID or Type.FILE");
Logger.diag("Writing file \"" + path + "\" (string, " + (async ? "async" : "dsync") + ")"); Logger.diag("Writing file \"" + path + "\" (string, " + (async ? "async" : "dsync") + ")");
Files.writeString(path, string, charset, StandardOpenOption.WRITE, async ? StandardOpenOption.DSYNC : StandardOpenOption.SYNC); 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 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} * @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 * @throws IOException on an IO error
* @return this instance * @return this instance
*/ */
public @NotNull FileAccess appendBytes(byte @NotNull [] bytes, boolean async) throws UnsupportedOperationException, IOException { public @NotNull FileAccess appendBytes(byte @NotNull [] bytes, boolean async) throws UnsupportedOperationException, IOException {
if (getType() == FileType.VOID) if (getType() == Type.VOID)
createFile(); createFile();
else if (getType() != FileType.FILE) else if (getType() != Type.FILE)
throw new UnsupportedOperationException("File \"" + path + "\" is not of type FileType.VOID or FileType.FILE"); throw new UnsupportedOperationException("File \"" + path + "\" is not of type Type.VOID or Type.FILE");
Logger.diag("Appending file \"" + path + "\" (bytes, " + (async ? "async" : "dsync") + ")"); Logger.diag("Appending file \"" + path + "\" (bytes, " + (async ? "async" : "dsync") + ")");
Files.write(path, bytes, StandardOpenOption.APPEND, async ? StandardOpenOption.DSYNC : StandardOpenOption.SYNC); 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 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} * @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 * @throws IOException on an IO error
* @return this instance * @return this instance
*/ */
@ -834,18 +834,53 @@ public final class FileAccess {
* @param string string to append * @param string string to append
* @param charset charset to encode the string in * @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} * @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 * @throws IOException on an IO error
* @return this instance * @return this instance
*/ */
public @NotNull FileAccess appendString(@NotNull String string, @NotNull Charset charset, boolean async) throws UnsupportedOperationException, IOException { public @NotNull FileAccess appendString(@NotNull String string, @NotNull Charset charset, boolean async) throws UnsupportedOperationException, IOException {
if (getType() == FileType.VOID) if (getType() == Type.VOID)
createFile(); createFile();
else if (getType() != FileType.FILE) else if (getType() != Type.FILE)
throw new UnsupportedOperationException("File \"" + path + "\" is not of type FileType.VOID or FileType.FILE"); throw new UnsupportedOperationException("File \"" + path + "\" is not of type Type.VOID or Type.FILE");
Logger.diag("Appending file \"" + path + "\" (string, " + (async ? "async" : "dsync") + ")"); Logger.diag("Appending file \"" + path + "\" (string, " + (async ? "async" : "dsync") + ")");
Files.writeString(path, string, charset, StandardOpenOption.APPEND, async ? StandardOpenOption.DSYNC : StandardOpenOption.SYNC); Files.writeString(path, string, charset, StandardOpenOption.APPEND, async ? StandardOpenOption.DSYNC : StandardOpenOption.SYNC);
return this; 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; package de.staropensource.engine.base.utility.information;
import de.staropensource.engine.base.logging.Logger; import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.type.immutable.ImmutableArrayList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage; import java.lang.management.MemoryUsage;
import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
@ -114,7 +114,7 @@ public final class JvmInformation {
* @since v1-alpha0 * @since v1-alpha0
*/ */
public static @NotNull List<@NotNull String> getArguments() { 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/>. * 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 org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.Collection;
import java.util.Map; 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 { public final class ListFormatter {
/** /**
* Creates and initializes an instance of this class. * Creates and initializes an instance of this class.
* *
* @since v1-alpha6 * @since v1-alpha9
*/ */
private ListFormatter() {} 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 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 * @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(); StringBuilder output = new StringBuilder();
for (int index = 0; index < array.length; index++) { for (int index = 0; index < array.length; index++) {
if (!output.isEmpty()) if (!output.isEmpty())
if (index == array.length - 1) if (index == array.length - 1)
output.append(" & "); output.append(finalSeparator);
else else
output.append(", "); output.append(itemSeparator);
output.append(array[index]); 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 * @return formatted string
* @since v1-alpha4 * @since v1-alpha9
*/ */
public static @NotNull String formatSet(@NotNull Set<?> set) { public static @NotNull String formatArray(@NotNull Object @NotNull [] array) {
return formatArray(set.toArray()); 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 * @return formatted string
* @since v1-alpha4 * @since v1-alpha9
*/ */
public static @NotNull String formatList(@NotNull List<?> list) { public static @NotNull String formatCollection(@NotNull Collection<?> collection, @NotNull String itemSeparator, @NotNull String finalSeparator) {
return formatArray(list.toArray()); 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 * @param map map to convert
* @return formatted string * @return formatted string
* @since v1-alpha4 * @since v1-alpha9
*/ */
public static @NotNull String formatMap(@NotNull Map<?, ?> map) { public static @NotNull String formatMap(@NotNull Map<?, ?> map) {
StringBuilder output = new StringBuilder(); 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/>. * 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 org.jetbrains.annotations.NotNull;
@ -27,31 +27,36 @@ import java.util.LinkedList;
/** /**
* Utility class for math operations. * Utility class for math operations.
* *
* @since v1-alpha2 * @since v1-alpha9
*/ */
// All mean and double methods have been sourced // All mean and double methods have been sourced
// from https://stackoverflow.com/a/4191729, tysm! // from https://stackoverflow.com/a/4191729, tysm!
@SuppressWarnings({ "unused" }) @SuppressWarnings({ "unused" })
public final class Math { public final class NumberUtil {
/** /**
* Creates and initializes an instance of this class * Creates and initializes an instance of this class
* *
* @since v1-alpha6 * @since v1-alpha9
*/ */
private Math() {} private NumberUtil() {}
/** /**
* Adds padding zeros to a number. * Adds padding zeros to a number.
* <p>
* Example:
* {@code padNumbers(505L, 5) = "00505"}
* *
* @param number number * @param number number
* @param length length * @param length length
* @return the padded number * @return the padded number
* @since v1-alpha2 * @since v1-alpha9
*/ */
public static @NotNull String padNumbers(long number, int length) { public static @NotNull String padNumbers(long number, int length) {
return String.format("%0" + length + "d", number); return String.format("%0" + length + "d", number);
} }
// -----> Number limiting
/** /**
* Ensures the integer is inside the * Ensures the integer is inside the
* specified bounds. If not, the * specified bounds. If not, the
@ -61,10 +66,10 @@ public final class Math {
* @param max maximum value * @param max maximum value
* @param value value * @param value value
* @return number in threshold * @return number in threshold
* @throws IndexOutOfBoundsException when the minimum value is bigger than the maximum value * @throws IndexOutOfBoundsException if the minimum value is bigger than the maximum value
* @since v1-alpha6 * @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) if (min > max)
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
@ -85,10 +90,10 @@ public final class Math {
* @param max maximum value * @param max maximum value
* @param value value * @param value value
* @return number in threshold * @return number in threshold
* @throws IndexOutOfBoundsException when the minimum value is bigger than the maximum value * @throws IndexOutOfBoundsException if the minimum value is bigger than the maximum value
* @since v1-alpha6 * @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) if (min > max)
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
@ -109,10 +114,10 @@ public final class Math {
* @param max maximum value * @param max maximum value
* @param value value * @param value value
* @return number in threshold * @return number in threshold
* @throws IndexOutOfBoundsException when the minimum value is bigger than the maximum value * @throws IndexOutOfBoundsException if the minimum value is bigger than the maximum value
* @since v1-alpha6 * @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) if (min > max)
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
@ -124,14 +129,16 @@ public final class Math {
return value; return value;
} }
// -----> Means and medians
/** /**
* Returns the mean of a collection of numbers. * Returns the mean of a collection of numbers.
* *
* @param collection collection of {@code double}s * @param collection collection of {@code double}s
* @return mean * @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; double sum = 0;
for (double number : collection) for (double number : collection)
@ -145,9 +152,9 @@ public final class Math {
* *
* @param collection collection of {@code float}s * @param collection collection of {@code float}s
* @return mean * @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; double sum = 0;
for (float number : collection) for (float number : collection)
@ -161,9 +168,9 @@ public final class Math {
* *
* @param collection collection of {@code long}s * @param collection collection of {@code long}s
* @return mean * @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; double sum = 0;
for (long number : collection) for (long number : collection)
@ -177,9 +184,9 @@ public final class Math {
* *
* @param collection collection of {@code int}s * @param collection collection of {@code int}s
* @return mean * @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; double sum = 0;
for (int number : collection) for (int number : collection)
@ -193,9 +200,9 @@ public final class Math {
* *
* @param list linked list of {@code double}s * @param list linked list of {@code double}s
* @return median * @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; int middle = list.size() / 2;
if (list.size() % 2 == 1) if (list.size() % 2 == 1)
return list.get(middle); return list.get(middle);
@ -208,9 +215,9 @@ public final class Math {
* *
* @param list linked list of {@code float}s * @param list linked list of {@code float}s
* @return median * @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; int middle = list.size() / 2;
if (list.size() % 2 == 1) if (list.size() % 2 == 1)
return list.get(middle); return list.get(middle);
@ -223,9 +230,9 @@ public final class Math {
* *
* @param list linked list of {@code long}s * @param list linked list of {@code long}s
* @return median * @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; int middle = list.size() / 2;
if (list.size() % 2 == 1) if (list.size() % 2 == 1)
return list.get(middle); return list.get(middle);
@ -238,9 +245,9 @@ public final class Math {
* *
* @param list linked list of {@code int}s * @param list linked list of {@code int}s
* @return median * @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; int middle = list.size() / 2;
if (list.size() % 2 == 1) if (list.size() % 2 == 1)
return list.get(middle); 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/>. * 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. }
*
* @since v1-alpha8 /**
*/ * Converts an integer into a {@link Tristate} and then into a boolean.
FILE, *
* @param integer integer to convert
/** * @return booleanized integer
* It's a directory containing files. * @since v1-alpha9
* */
* @since v1-alpha8 public static boolean integerToBoolean(@Range(from = 0, to = 1) int integer) throws IndexOutOfBoundsException {
*/ return integer != 0;
DIRECTORY, }
/**
* The file type is unknown to the sos!engine.
*
* @since v1-alpha8
*/
UNKNOWN
} }

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. * 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 * @since v1-alpha0
*/ */
package de.staropensource.engine.base.utility; 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.implementation.logging;
exports de.staropensource.engine.base.reflection; exports de.staropensource.engine.base.reflection;
exports de.staropensource.engine.base.type; 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.logging;
exports de.staropensource.engine.base.type.reflection; exports de.staropensource.engine.base.type.reflection;
exports de.staropensource.engine.base.type.vector; exports de.staropensource.engine.base.type.vector;
exports de.staropensource.engine.base.utility; exports de.staropensource.engine.base.utility;
exports de.staropensource.engine.base.utility.misc;
// Reflection access // Reflection access
opens de.staropensource.engine.base; opens de.staropensource.engine.base;
@ -52,9 +52,9 @@ module sosengine.base {
opens de.staropensource.engine.base.implementation.logging; opens de.staropensource.engine.base.implementation.logging;
opens de.staropensource.engine.base.reflection; opens de.staropensource.engine.base.reflection;
opens de.staropensource.engine.base.type; 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.logging;
opens de.staropensource.engine.base.type.reflection; opens de.staropensource.engine.base.type.reflection;
opens de.staropensource.engine.base.type.vector; opens de.staropensource.engine.base.type.vector;
opens de.staropensource.engine.base.utility; 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.EngineConfiguration;
import de.staropensource.engine.base.annotation.EventListener; 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.testing.TestBase;
import de.staropensource.engine.base.utility.Math; import de.staropensource.engine.base.utility.misc.NumberUtil;
import de.staropensource.engine.base.utility.Miscellaneous; import de.staropensource.engine.base.utility.misc.Miscellaneous;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -66,7 +64,7 @@ public class MiscellaneousTest extends TestBase {
if (performMethodCalls("testPadNumbers", number, length, expected)) if (performMethodCalls("testPadNumbers", number, length, expected))
return; return;
String result = Math.padNumbers(number, length); String result = NumberUtil.padNumbers(number, length);
assertEquals(expected, result, "Result \"" + result + "\" does not match expected output \"" + expected + "\""); assertEquals(expected, result, "Result \"" + result + "\" does not match expected output \"" + expected + "\"");
} }
@ -98,7 +96,7 @@ public class MiscellaneousTest extends TestBase {
*/ */
@Test @Test
@DisplayName("getMapValues") @DisplayName("getMapValues")
void testGetMapValues() { void testSearchForValueInMap() {
if (performMethodCalls("testGetMapValues")) if (performMethodCalls("testGetMapValues"))
return; return;
@ -109,28 +107,13 @@ public class MiscellaneousTest extends TestBase {
testMap.put("keylast", "this is the last value"); testMap.put("keylast", "this is the last value");
testMap.put("keylast2", "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("keytwo"), "Map key \"keytwo\" not found in output Set");
assertTrue(output.contains("keydrei"), "Map key \"keydrei\" 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"); 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}. * 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.EngineConfiguration;
import de.staropensource.engine.base.logging.Logger; import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.type.logging.LogLevel; import de.staropensource.engine.base.type.logging.LogLevel;
import de.staropensource.engine.base.utility.Miscellaneous;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.slf4j.Marker; import org.slf4j.Marker;
import org.slf4j.event.Level; import org.slf4j.event.Level;

View file

@ -86,6 +86,9 @@ application {
// reflective sclasspath scanning is disabled. // 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", "-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 // Force Jansi to write escape sequences
"-Djansi.mode=force", "-Djansi.mode=force",
] ]
@ -129,6 +132,7 @@ tasks.register('runNativeImage', Exec) {
"-Dsosengine.base.logForceStandardOutput=true", "-Dsosengine.base.logForceStandardOutput=true",
"-Dsosengine.base.initialForceDisableClasspathScanning=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.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", "-Djansi.mode=force",
) )
executable("build/bin/sosengine-testapp") 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.implementable.helper.EventHelper;
import de.staropensource.engine.base.logging.Logger; import de.staropensource.engine.base.logging.Logger;
import de.staropensource.engine.base.type.vector.Vec2i; 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.RenderingSubsystem;
import de.staropensource.engine.rendering.event.InputEvent; import de.staropensource.engine.rendering.event.InputEvent;
import de.staropensource.engine.rendering.type.Window; import de.staropensource.engine.rendering.type.Window;
@ -135,8 +135,10 @@ public final class Main {
return; return;
} }
if (window == null) if (window == null) {
Logger.crash("'window' is null"); Logger.crash("'window' is null");
return;
}
// Render loop // Render loop
LinkedHashMap<@NotNull Window, @NotNull Throwable> renderLoopFailures = RenderingSubsystem LinkedHashMap<@NotNull Window, @NotNull Throwable> renderLoopFailures = RenderingSubsystem
@ -146,6 +148,7 @@ public final class Main {
Engine.getInstance().shutdown(); Engine.getInstance().shutdown();
}); });
// Print render loop failures // Print render loop failures
StringBuilder message = new StringBuilder(); StringBuilder message = new StringBuilder();
message.append("Render loop failed on some windows:\n"); message.append("Render loop failed on some windows:\n");
@ -155,9 +158,9 @@ public final class Main {
.append("-> ") .append("-> ")
.append(window) .append(window)
.append(": ") .append(": ")
.append(Miscellaneous.getStackTraceHeader(renderLoopFailures.get(windowFailed))) .append(Miscellaneous.getThrowableHeader(renderLoopFailures.get(windowFailed)))
.append("\n") .append("\n")
.append(Miscellaneous.getStackTraceAsString(renderLoopFailures.get(windowFailed), true)) .append(Miscellaneous.stackTraceAsString(renderLoopFailures.get(windowFailed), true))
.append("\n"); .append("\n");
Logger.crash(message.toString()); Logger.crash(message.toString());