Skip to content

Commit

Permalink
Added new annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
p0loskun committed Feb 17, 2024
1 parent a70c934 commit 9c494c1
Show file tree
Hide file tree
Showing 21 changed files with 504 additions and 117 deletions.
4 changes: 3 additions & 1 deletion src/main/java/com/minersstudios/mscore/MSCore.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.minersstudios.mscore;

import com.minersstudios.mscore.annotation.Namespace;
import com.minersstudios.mscore.plugin.MSLogger;
import com.minersstudios.mscore.plugin.MSPlugin;
import com.minersstudios.mscore.utility.CoreProtectUtils;
Expand All @@ -22,7 +23,8 @@
public final class MSCore extends MSPlugin<MSCore> {
private static MSCore singleton;

public static final String NAMESPACE = "mscore";
/** The namespace of the plugin */
public static final @Namespace String NAMESPACE = "mscore";

//<editor-fold desc="Config keys" defaultstate="collapsed">
private static final String KEY_CONNECTION_THROTTLE = "messages.kick.connection-throttle";
Expand Down
97 changes: 97 additions & 0 deletions src/main/java/com/minersstudios/mscore/annotation/Key.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.minersstudios.mscore.annotation;

import com.minersstudios.mscore.throwable.InvalidRegexException;
import org.intellij.lang.annotations.RegExp;
import org.intellij.lang.annotations.Subst;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.regex.Pattern;

import static java.lang.annotation.ElementType.*;

/**
* Annotation used to mark the key.
* <br>
* The key must match the {@link #REGEX regex} pattern.
*
* @see Key.Validator
*/
@Documented
@Retention(RetentionPolicy.CLASS)
@Target({
FIELD,
LOCAL_VARIABLE,
METHOD,
PARAMETER
})
@org.intellij.lang.annotations.Pattern(Key.REGEX)
public @interface Key {
/** The regex pattern that a valid key must match */
@RegExp String REGEX = "[a-z0-9/._-]*";

/** The compiled Pattern of the {@link #REGEX regex} string */
Pattern PATTERN = Pattern.compile(REGEX);

/**
* Validator class for the {@link Key} annotation to check whether the
* key matches the {@link #REGEX regex}
*
* @see #matches(String)
* @see #validate(String)
*/
final class Validator {

@Contract(" -> fail")
private Validator() throws AssertionError {
throw new AssertionError("Utility class");
}

/**
* Checks whether the key matches the {@link #REGEX regex}
*
* @param key The key
* @return Whether the key matches the {@link #REGEX regex}
*/
public static boolean matches(final @Subst("key") @Key @Nullable String key) {
if (key == null) {
return true;
}

for(int i = 0; i < key.length(); ++i) {
final char character = key.charAt(i);

switch (character) {
case '_', '-', '.', '/' -> {}
default -> {
if (character < 'a' || character > 'z') {
if (character < '0' || character > '9') {
return false;
}
}
}
}
}

return true;
}

/**
* Validates the key
*
* @param key The key
* @throws InvalidRegexException If the key does not match the
* {@link #REGEX regex}
* @see #matches(String)
*/
public static void validate(final @Subst("key") @Key @Nullable String key) throws InvalidRegexException {
if (!matches(key)) {
throw new InvalidRegexException("Key must match regex: " + REGEX);
}
}
}
}
97 changes: 97 additions & 0 deletions src/main/java/com/minersstudios/mscore/annotation/Namespace.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.minersstudios.mscore.annotation;

import com.minersstudios.mscore.throwable.InvalidRegexException;
import org.intellij.lang.annotations.RegExp;
import org.intellij.lang.annotations.Subst;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.regex.Pattern;

import static java.lang.annotation.ElementType.*;

/**
* Annotation used to mark the namespace.
* <br>
* The namespace must match the {@link #REGEX regex} pattern.
*
* @see Namespace.Validator
*/
@Documented
@Retention(RetentionPolicy.CLASS)
@Target({
FIELD,
LOCAL_VARIABLE,
METHOD,
PARAMETER
})
@org.intellij.lang.annotations.Pattern(Namespace.REGEX)
public @interface Namespace {
/** The regex pattern that a valid namespace must match */
@RegExp String REGEX = "[a-z0-9._-]*";

/** The compiled Pattern of the {@link #REGEX regex} string */
Pattern PATTERN = Pattern.compile(REGEX);

/**
* Validator class for the {@link Namespace} annotation to check whether the
* namespace matches the {@link #REGEX regex}
*
* @see #matches(String)
* @see #validate(String)
*/
final class Validator {

@Contract(" -> fail")
private Validator() throws AssertionError {
throw new AssertionError("Utility class");
}

/**
* Checks whether the namespace matches the {@link #REGEX regex}
*
* @param namespace The namespace
* @return Whether the namespace matches the {@link #REGEX regex}
*/
public static boolean matches(final @Subst("namespace") @Namespace @Nullable String namespace) {
if (namespace == null) {
return false;
}

for(int i = 0; i < namespace.length(); ++i) {
final char character = namespace.charAt(i);

switch (character) {
case '_', '-', '.' -> {}
default -> {
if (character < 'a' || character > 'z') {
if (character < '0' || character > '9') {
return false;
}
}
}
}
}

return true;
}

/**
* Validates the namespace
*
* @param namespace The namespace
* @throws InvalidRegexException If the namespace does not match the
* {@link #REGEX regex}
* @see #matches(String)
*/
public static void validate(final @Subst("namespace") @Namespace @Nullable String namespace) throws InvalidRegexException {
if (!matches(namespace)) {
throw new InvalidRegexException("Namespace must match regex: " + REGEX);
}
}
}
}
97 changes: 97 additions & 0 deletions src/main/java/com/minersstudios/mscore/annotation/ResourceKey.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.minersstudios.mscore.annotation;

import com.minersstudios.mscore.throwable.InvalidRegexException;
import org.bukkit.NamespacedKey;
import org.intellij.lang.annotations.RegExp;
import org.intellij.lang.annotations.Subst;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.regex.Pattern;

import static java.lang.annotation.ElementType.*;

/**
* Annotation used to mark the {@link NamespacedKey namespaced-key}.
* <br>
* The namespaced-key must match the {@link #REGEX regex} pattern.
*
* @see ResourceKey.Validator
*/
@Documented
@Retention(RetentionPolicy.CLASS)
@Target({
FIELD,
LOCAL_VARIABLE,
METHOD,
PARAMETER
})
@org.intellij.lang.annotations.Pattern(ResourceKey.REGEX)
public @interface ResourceKey {
/** The regex pattern that a valid namespaced-key must match */
@RegExp String REGEX = "(" + Namespace.REGEX + ")(:(" + Key.REGEX + "))?";

/** The compiled Pattern of the {@link #REGEX regex} string */
Pattern PATTERN = Pattern.compile(REGEX);

/**
* Validator class for the {@link ResourceKey} annotation to check whether
* the namespaced-key matches the {@link #REGEX regex}
*
* @see #matches(String)
* @see #validate(String)
*/
final class Validator {

@Contract(" -> fail")
private Validator() throws AssertionError {
throw new AssertionError("Utility class");
}

/**
* Checks whether the namespaced-key matches the {@link #REGEX regex}
*
* @param namespacedKey The namespaced-key
* @return Whether the namespaced-key matches the {@link #REGEX regex}
*/
public static boolean matches(final @Subst("namespace:key") @ResourceKey @Nullable String namespacedKey) {
if (namespacedKey == null) {
return true;
}

final int colonIndex = namespacedKey.indexOf(':');

@Subst("namespace") String namespace = "";
@Subst("key") String key = namespacedKey;

if (colonIndex >= 0) {
key = namespacedKey.substring(colonIndex + 1);

if (colonIndex >= 1) {
namespace = namespacedKey.substring(0, colonIndex);
}
}

return Namespace.Validator.matches(namespace)
&& Key.Validator.matches(key);
}

/**
* Validates the namespaced-key
*
* @param namespacedKey The namespaced-key
* @throws InvalidRegexException If the namespaced-key does not match
* the {@link #REGEX regex}
* @see #matches(String)
*/
public static void validate(final @Subst("namespace:key") @ResourceKey @Nullable String namespacedKey) throws InvalidRegexException {
if (!matches(namespacedKey)) {
throw new InvalidRegexException("NamespacedKey must match regex: " + REGEX);
}
}
}
}
Loading

0 comments on commit 9c494c1

Please sign in to comment.