Skip to content

Commit

Permalink
Merge pull request #28 from JuliGames/development
Browse files Browse the repository at this point in the history
Version 1.5
  • Loading branch information
TureBentzin authored Mar 23, 2023
2 parents 3a6bf84 + 8e2a353 commit 2873eea
Show file tree
Hide file tree
Showing 80 changed files with 2,486 additions and 299 deletions.
10 changes: 8 additions & 2 deletions API/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<artifactId>JuliGamesCore</artifactId>
<groupId>net.juligames.core</groupId>
<version>1.4</version>
<version>1.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down Expand Up @@ -58,7 +58,13 @@
<dependency>
<groupId>de.bentzin.tools</groupId>
<artifactId>DevTools</artifactId>
<version>2.2</version>
<version>2.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
<scope>compile</scope>
</dependency>

Expand Down
19 changes: 19 additions & 0 deletions API/src/main/java/net/juligames/core/api/API.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,30 @@ public interface API {
* @return your API Instance
* @throws APIException if no API is present
*/
@SuppressWarnings("SpellCheckingInspection")
static @NotNull API get() throws APIException {
@MaybePresent Optional<API> api = ApiProvider.optionalApi();
if (api.isEmpty()) {
throw new APIException();
}
if (!Boolean.getBoolean("acknowledgeMissingCoreClass")) {
//this block provides security over the used implementation of the API class!
try {
Class.forName("net.juligames.core.Core"); //check that the core is installed
} catch (ClassNotFoundException e) {
try {
api.ifPresent(api1 -> {
api1.getAPILogger().error("Error while providing this instance: " + e.getMessage() + "!");
api1.getAPILogger().error("It seems like you are operating an unsupported implementation of the Core! \n" +
"You can acknowledge this dangerous behavior by setting the \"-DacknowledgeMissingCoreClass=true\"!");
});
} catch (Exception ignored) {
//ok its fucked
throw new APIException(e);
}
throw new APIException(e);
}
}
return api.get();
}

Expand Down
1 change: 1 addition & 0 deletions API/src/main/java/net/juligames/core/api/TODO.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* @apiNote Methods annotated with this might throw a {@link net.juligames.core.api.err.dev.TODOException}
* @suppression may suppress convert to record and unused
*/
@SuppressWarnings("JavadocDeclaration")
public @interface TODO {
boolean doNotcall();
}
10 changes: 10 additions & 0 deletions API/src/main/java/net/juligames/core/api/cacheing/CacheApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import de.bentzin.tools.pair.Pair;
import net.juligames.core.api.config.Interpreter;
import net.juligames.core.api.jdbi.DBMessage;
import org.jetbrains.annotations.ApiStatus;

import java.util.Map;

/**
* @author Ture Bentzin
Expand All @@ -20,6 +24,12 @@ public interface CacheApi {
*/
<K, V> Cache<K, V> newCache();

@ApiStatus.AvailableSince("1.5")
<K, V> Map<String, String> reverseCache(Interpreter<K> kInterpreter, Interpreter<V> vInterpreter, Cache<K, V> cache);

@ApiStatus.AvailableSince("1.5")
<K, V> Map<K, V> interpretCache(Interpreter<K> kInterpreter, Interpreter<V> vInterpreter, Cache<String, String> cache);

/**
* Creates a builder to create your custom caches by default this will enter the suggested settings
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
package net.juligames.core.api.config;

import net.juligames.core.api.API;
import net.juligames.core.api.jdbi.DBData;
import net.juligames.core.api.jdbi.DataDAO;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.net.URI;
import java.net.URL;
import java.text.DateFormat;
import java.time.DateTimeException;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.TemporalUnit;
import java.util.Date;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.UUID;

/**
Expand Down Expand Up @@ -51,5 +60,74 @@ public interface BuildInInterpreters {
return s -> s;
}

@ApiStatus.AvailableSince("1.5")
@Contract(pure = true)
static @NotNull Interpreter<Class<?>> clazzInterpreter() {
return new Interpreter<>() {
@Override
public @NotNull Class<?> interpret(@NotNull String input) throws Exception {
return Class.forName(input);
}

@Override
public @NotNull String reverse(@NotNull Class<?> tClass) {
return tClass.getName();
}
};
}


@ApiStatus.AvailableSince("1.5")
@Contract(value = "_ -> new", pure = true)
static @NotNull Interpreter<Configuration> onlineConfigurationInterpreter(boolean createIfNotExists) {
return new Interpreter<>() {
@Override
public @NotNull Configuration interpret(@NotNull String input) throws Exception {
if (!createIfNotExists && !API.get().getConfigurationApi().exists(input)) {
throw new NoSuchElementException(input + " has no associated configuration!");
}
return API.get().getConfigurationApi().getOrCreate(input);
}

@Override
public @NotNull String reverse(@NotNull Configuration configuration) {
return configuration.getName();
}
};
}

@Contract(value = "_ -> new", pure = true)
@ApiStatus.AvailableSince("1.5")
static @NotNull Interpreter<Duration> durationInterpreter(TemporalUnit unit) {
return new Interpreter<>() {
@Override
public @NotNull Duration interpret(String input) throws DateTimeException, ArithmeticException, NumberFormatException {
return Duration.of(Long.parseLong(input), unit);
}

@Override
public @NotNull String reverse(Duration duration) {
return String.valueOf(duration.get(unit));
}
};
}

@Contract(value = " -> new", pure = true)
@ApiStatus.Experimental
@ApiStatus.AvailableSince("1.5")
static @NotNull Interpreter<DBData> dbDataInterpreter() {
return new Interpreter<>() {
@Override
public @NotNull DBData interpret(String input) throws Exception {
return Objects.requireNonNull(API.get().getSQLManager().withExtension(DataDAO.class, extension ->
extension.select(input)));
}

@Override
public @NotNull String reverse(DBData dbData) {
return dbData.getKey();
}
};
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package net.juligames.core.api.config;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

/**
* @author Ture Bentzin
* 10.01.2023
*/
@ApiStatus.Experimental
public interface ConfigWriter {
/**
* Writes the data of this {@link ConfigWriter} to the configuration
Expand Down
153 changes: 152 additions & 1 deletion API/src/main/java/net/juligames/core/api/config/Configuration.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package net.juligames.core.api.config;

import de.bentzin.tools.pair.BasicPair;
import de.bentzin.tools.pair.EntryPairAdapter;
import de.bentzin.tools.pair.Pair;
import net.juligames.core.api.misc.TriConsumer;
import org.checkerframework.checker.optional.qual.MaybePresent;
import org.jetbrains.annotations.ApiStatus;
Expand All @@ -11,6 +13,7 @@
import java.io.OutputStream;
import java.util.*;
import java.util.function.*;
import java.util.stream.Stream;

/**
* @author Ture Bentzin
Expand All @@ -20,7 +23,8 @@
* @see BuildInInterpreters
*/
@SuppressWarnings("unused")
public interface Configuration extends Comparable<Configuration> {
public interface Configuration extends Comparable<Configuration>, Iterable<Pair<String>> {


/**
* This keys can be requested but never should be overridden (it is possible to override them, but only consider doing this if you really
Expand Down Expand Up @@ -209,6 +213,73 @@ public interface Configuration extends Comparable<Configuration> {

void set(@NotNull BasicPair<String, String> basicPair);

//ifAbsent

@ApiStatus.AvailableSince("1.5")
void setStringIfAbsent(@NotNull String key, @NotNull String value);

@ApiStatus.AvailableSince("1.5")
void setStringIfAbsent(@NotNull String key, @NotNull Supplier<String> value);

@ApiStatus.AvailableSince("1.5")
void setIntegerIfAbsent(@NotNull String key, @NotNull Integer value);

@ApiStatus.AvailableSince("1.5")
void setIntegerIfAbsent(@NotNull String key, @NotNull Supplier<Integer> value);

@ApiStatus.AvailableSince("1.5")
void setDoubleIfAbsent(@NotNull String key, @NotNull Double value);

@ApiStatus.AvailableSince("1.5")
void setDoubleIfAbsent(@NotNull String key, @NotNull Supplier<Double> value);

@ApiStatus.AvailableSince("1.5")
void setLongIfAbsent(@NotNull String key, @NotNull Long value);

@ApiStatus.AvailableSince("1.5")
void setLongIfAbsent(@NotNull String key, @NotNull Supplier<Long> value);

@ApiStatus.AvailableSince("1.5")
void setShortIfAbsent(@NotNull String key, @NotNull Short value);

@ApiStatus.AvailableSince("1.5")
void setShortIfAbsent(@NotNull String key, @NotNull Supplier<Short> value);

@ApiStatus.AvailableSince("1.5")
void setByteIfAbsent(@NotNull String key, @NotNull Byte value);

@ApiStatus.AvailableSince("1.5")
void setByteIfAbsent(@NotNull String key, @NotNull Supplier<Byte> value);

@ApiStatus.AvailableSince("1.5")
void setBooleanIfAbsent(@NotNull String key, @NotNull Boolean value);

@ApiStatus.AvailableSince("1.5")
void setBooleanIfAbsent(@NotNull String key, @NotNull Supplier<Boolean> value);

@ApiStatus.AvailableSince("1.5")
void setFloatIfAbsent(@NotNull String key, @NotNull Float value);

@ApiStatus.AvailableSince("1.5")
void setFloatIfAbsent(@NotNull String key, @NotNull Supplier<Float> value);

@ApiStatus.AvailableSince("1.5")
<T> void setIfAbsent(@NotNull String key, @NotNull T value, @NotNull Interpreter<T> interpreter);

@ApiStatus.AvailableSince("1.5")
<T> void setIfAbsent(@NotNull String key, @NotNull Supplier<T> value, @NotNull Interpreter<T> interpreter);

@ApiStatus.AvailableSince("1.5")
<T> void setIfAbsent(@NotNull Supplier<String> key, @NotNull T value, @NotNull Interpreter<T> interpreter);

@ApiStatus.AvailableSince("1.5")
<T> void setIfAbsent(@NotNull Supplier<String> key, @NotNull Supplier<T> value, @NotNull Interpreter<T> interpreter);

@ApiStatus.AvailableSince("1.5")
void setIfAbsent(@NotNull BasicPair<String, String> basicPair);

//del

void del(@NotNull String key);

void del(@NotNull Supplier<String> keys);
Expand Down Expand Up @@ -261,12 +332,92 @@ public interface Configuration extends Comparable<Configuration> {
@ApiStatus.AvailableSince("1.4")
<R> R doWithData(@NotNull Function<Map<String, String>, R> function);

/**
* @deprecated this method can have serious effects on the integrity of the data managed by the configuration!
* Because of this thread the {@link #setStringIfAbsent(String, String)} methods where introduced. Removal of this method
* may be accomplished later. It is not unlikely that this method will be stripped of its manipulation capabilities and
* will serve only for query operations!
*/
@ApiStatus.Experimental
@ApiStatus.AvailableSince("1.4")
@Deprecated
void doWithData(@NotNull Consumer<Map<String, String>> action);

@Override
default int compareTo(@NotNull Configuration o) {
return o.size() - size();
}

@ApiStatus.AvailableSince("1.5")
@ApiStatus.Experimental
@NotNull
Stream<String> searchValue(@NotNull String value);

@ApiStatus.AvailableSince("1.5")
@NotNull String getName();

//from map

/**
* Performs the given action for each entry in this configuration until all entries
* have been processed or the action throws an exception. Unless
* otherwise specified by the implementing class, actions are performed in
* the order of entry set iteration (if an iteration order is specified.)
* Exceptions thrown by the action are relayed to the caller.
*
* @param action The action to be performed for each entry
* @throws NullPointerException if the specified action is null
* @throws ConcurrentModificationException if an entry is found to be
* removed during iteration
* @implSpec The default implementation is equivalent to, for this {@code configuration}:
* <pre> {@code
* for (Map.Entry<String, String> entry : configuration.entrySet())
* action.accept(entry.getKey(), entry.getValue());
* }</pre>
* <p>
* The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
* atomicity guarantees must override this method and document its
* concurrency properties.
*/
@ApiStatus.AvailableSince("1.5")
default void forEach(BiConsumer<String, String> action) {
Objects.requireNonNull(action);
for (Map.Entry<String, String> entry : entrySet()) {
String k;
String v;
try {
k = entry.getKey();
v = entry.getValue();
} catch (IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
action.accept(k, v);
}
}


//Iterable

@NotNull
@Override
@ApiStatus.AvailableSince("1.5")
default Iterator<Pair<String>> iterator() {
return entrySet().stream().map(EntryPairAdapter::pairFromEntry).iterator();
}

@Override
@ApiStatus.AvailableSince("1.5")
default void forEach(Consumer<? super Pair<String>> action) {
forEach((s, s2) -> action.accept(new Pair<>(s, s2)));
}

@Override
@ApiStatus.AvailableSince("1.5")
default Spliterator<Pair<String>> spliterator() {
return entrySet().stream().map(EntryPairAdapter::pairFromEntry).spliterator();
}


}
Loading

0 comments on commit 2873eea

Please sign in to comment.