mirror of
https://github.com/YouHaveTrouble/BlockEdit.git
synced 2026-06-29 13:36:19 +00:00
expanded the schematic api draft
This commit is contained in:
@@ -1,8 +1,13 @@
|
|||||||
package me.youhavetrouble.blockedit;
|
package me.youhavetrouble.blockedit;
|
||||||
|
|
||||||
|
import me.youhavetrouble.blockedit.exception.SchematicHandlerRegistrationException;
|
||||||
|
import me.youhavetrouble.blockedit.exception.SchematicLoadException;
|
||||||
|
import me.youhavetrouble.blockedit.exception.SchematicSaveException;
|
||||||
|
import me.youhavetrouble.blockedit.schematic.FileSchematicProvider;
|
||||||
import me.youhavetrouble.blockedit.schematic.Schematic;
|
import me.youhavetrouble.blockedit.schematic.Schematic;
|
||||||
import me.youhavetrouble.blockedit.schematic.SchematicProvider;
|
import me.youhavetrouble.blockedit.schematic.SchematicProvider;
|
||||||
import me.youhavetrouble.blockedit.util.Clipboard;
|
import me.youhavetrouble.blockedit.util.Clipboard;
|
||||||
|
import me.youhavetrouble.blockedit.util.NameFilenameFilter;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -17,7 +22,7 @@ public class SchematicHandler<S extends Schematic> {
|
|||||||
private final Map<String, SchematicProvider<S>> schematicProvidersByExtension = new HashMap<>();
|
private final Map<String, SchematicProvider<S>> schematicProvidersByExtension = new HashMap<>();
|
||||||
private final Map<String, SchematicProvider<S>> schematicProvidersByName = new HashMap<>();
|
private final Map<String, SchematicProvider<S>> schematicProvidersByName = new HashMap<>();
|
||||||
|
|
||||||
private final File schematicsDirectory;
|
public final File schematicsDirectory;
|
||||||
|
|
||||||
protected SchematicHandler(BlockEdit plugin) {
|
protected SchematicHandler(BlockEdit plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
@@ -35,40 +40,53 @@ public class SchematicHandler<S extends Schematic> {
|
|||||||
|
|
||||||
public void registerSchematicProvider(
|
public void registerSchematicProvider(
|
||||||
@NotNull SchematicProvider<S> schematicProvider
|
@NotNull SchematicProvider<S> schematicProvider
|
||||||
) throws IllegalArgumentException {
|
) throws SchematicHandlerRegistrationException {
|
||||||
if (!schematicProvider.name().matches("^[a-z0-9]+$")) {
|
|
||||||
throw new IllegalArgumentException("Schematic provider name can only contain lowercase letters and numbers");
|
String schematicProviderName = schematicProvider.name().trim();
|
||||||
|
|
||||||
|
if (!schematicProviderName.matches("^[a-z0-9]+$")) {
|
||||||
|
throw new SchematicHandlerRegistrationException("Schematic provider name can only contain lowercase letters and numbers", schematicProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schematicProvidersByName.containsKey(schematicProvider.name())) {
|
if (schematicProvidersByName.containsKey(schematicProviderName)) {
|
||||||
throw new IllegalArgumentException("Schematic provider " + schematicProvider.name() + " is already registered");
|
throw new SchematicHandlerRegistrationException("Schematic provider with name " + schematicProvider.name() + " is already registered", schematicProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop extensions to verify if they're valid and not already registered
|
// Register the provider as a file provider that associates the provider with file extensions
|
||||||
for (String extension : schematicProvider.fileExtensions()) {
|
if (schematicProvider instanceof FileSchematicProvider<S> fileSchematicProvider) {
|
||||||
String trimmedExtension = extension.trim();
|
// Loop extensions to verify if they're valid and not already registered
|
||||||
if (trimmedExtension.isEmpty()) throw new IllegalArgumentException("File extension cannot be empty");
|
for (String extension : fileSchematicProvider.fileExtensions()) {
|
||||||
if (!trimmedExtension.matches("^[a-z0-9]+$")) throw new IllegalArgumentException("File extension can only contain lowercase letters and numbers");
|
String trimmedExtension = extension.trim();
|
||||||
if (schematicProvidersByExtension.containsKey(trimmedExtension)) {
|
if (trimmedExtension.isEmpty()) throw new SchematicHandlerRegistrationException("File extension cannot be empty", fileSchematicProvider);
|
||||||
throw new IllegalArgumentException("File extension " + trimmedExtension + " is already registered to " + schematicProvidersByExtension.get(trimmedExtension).name());
|
if (!trimmedExtension.matches("^[a-z0-9]+$")) throw new SchematicHandlerRegistrationException("File extension can only contain lowercase letters and numbers", fileSchematicProvider);
|
||||||
|
if (schematicProvidersByExtension.containsKey(trimmedExtension)) {
|
||||||
|
throw new SchematicHandlerRegistrationException("File extension " + trimmedExtension + " is already registered to " + schematicProvidersByExtension.get(trimmedExtension).name(), fileSchematicProvider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// Loop again to actually register the extensions
|
||||||
|
for (String extension : fileSchematicProvider.fileExtensions()) {
|
||||||
|
String trimmedExtension = extension.trim();
|
||||||
|
schematicProvidersByExtension.put(trimmedExtension, schematicProvider);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop again to actually register the extensions
|
|
||||||
for (String extension : schematicProvider.fileExtensions()) {
|
|
||||||
String trimmedExtension = extension.trim();
|
|
||||||
schematicProvidersByExtension.put(trimmedExtension, schematicProvider);
|
|
||||||
}
|
|
||||||
schematicProvidersByName.put(schematicProvider.name(), schematicProvider);
|
schematicProvidersByName.put(schematicProvider.name(), schematicProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a schematic from the schematics directory
|
* Loads a schematic from the schematic provider
|
||||||
* @param providerName Schematic provider to use
|
* @param providerName Schematic provider to use
|
||||||
* @param schematicName Name of the schematic
|
* @param schematicName Name of the schematic
|
||||||
* @return Clipboard object containing the schematic. Null if schematic does not exist or could not be loaded.
|
* @return Clipboard object containing the schematic. Null if schematic does not exist or could not be loaded.
|
||||||
*/
|
*/
|
||||||
public @Nullable Schematic loadSchematic(String providerName, @NotNull String schematicName) {
|
public @Nullable Schematic loadSchematic(@NotNull String providerName, @NotNull String schematicName) {
|
||||||
|
|
||||||
|
// file provider is a special case here
|
||||||
|
if (providerName.equals("file")) {
|
||||||
|
return loadSchematic(schematicName);
|
||||||
|
}
|
||||||
|
|
||||||
SchematicProvider<? extends Schematic> schematicProvider = schematicProvidersByName.get(providerName);
|
SchematicProvider<? extends Schematic> schematicProvider = schematicProvidersByName.get(providerName);
|
||||||
if (schematicProvider == null) {
|
if (schematicProvider == null) {
|
||||||
throw new IllegalArgumentException("Schematic provider " + providerName + " is not registered");
|
throw new IllegalArgumentException("Schematic provider " + providerName + " is not registered");
|
||||||
@@ -76,6 +94,34 @@ public class SchematicHandler<S extends Schematic> {
|
|||||||
return schematicProvider.load(schematicName);
|
return schematicProvider.load(schematicName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a schematic from the schematic directory. File schematic provider will be matched by the file extenstion
|
||||||
|
* @param schematicName File name without extension
|
||||||
|
* @return Schematic object
|
||||||
|
*/
|
||||||
|
public @Nullable Schematic loadSchematic(@NotNull String schematicName) throws SchematicLoadException {
|
||||||
|
File[] files;
|
||||||
|
try {
|
||||||
|
files = this.schematicsDirectory.listFiles(new NameFilenameFilter(schematicName));
|
||||||
|
if (files == null || files.length == 0) return null;
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
throw new SchematicLoadException("Could not list schematics directory", schematicName, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
File schematicFile = files[0];
|
||||||
|
String fileName = schematicFile.getName();
|
||||||
|
String fileExtension = fileName.substring(fileName.lastIndexOf('.') + 1);
|
||||||
|
SchematicProvider<S> schematicProvider = schematicProvidersByExtension.get(fileExtension);
|
||||||
|
if (schematicProvider == null) {
|
||||||
|
throw new SchematicLoadException("No schematic provider found for file extension " + fileExtension, schematicName);
|
||||||
|
}
|
||||||
|
Schematic schematic = schematicProvider.load(schematicName);
|
||||||
|
if (schematic == null) {
|
||||||
|
throw new SchematicLoadException("Schematic could not be loaded", schematicName);
|
||||||
|
}
|
||||||
|
return schematic;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves a schematic to the schematics directory
|
* Saves a schematic to the schematics directory
|
||||||
* @param schematicName Name of the schematic
|
* @param schematicName Name of the schematic
|
||||||
@@ -85,15 +131,13 @@ public class SchematicHandler<S extends Schematic> {
|
|||||||
@NotNull String schematicName,
|
@NotNull String schematicName,
|
||||||
@NotNull String providerName,
|
@NotNull String providerName,
|
||||||
@NotNull Clipboard clipboard
|
@NotNull Clipboard clipboard
|
||||||
) {
|
) throws SchematicSaveException {
|
||||||
SchematicProvider<S> schematicProvider = schematicProvidersByName.get(providerName);
|
SchematicProvider<S> schematicProvider = schematicProvidersByName.get(providerName);
|
||||||
if (schematicProvider == null) {
|
if (schematicProvider == null) {
|
||||||
throw new IllegalArgumentException("Schematic provider " + providerName + " is not registered");
|
throw new SchematicSaveException("Schematic provider " + providerName + " is not registered", schematicName);
|
||||||
}
|
}
|
||||||
S schematic = schematicProvider.fromClipboard(schematicName, clipboard);
|
S schematic = schematicProvider.fromClipboard(schematicName, clipboard);
|
||||||
|
|
||||||
schematicProvider.save(schematic);
|
schematicProvider.save(schematic);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package me.youhavetrouble.blockedit.exception;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class SchematicException extends RuntimeException {
|
||||||
|
|
||||||
|
private final String schematicName;
|
||||||
|
|
||||||
|
public SchematicException(@NotNull String message, @Nullable String schematicName, Throwable cause) {
|
||||||
|
super(message);
|
||||||
|
this.schematicName = schematicName;
|
||||||
|
initCause(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SchematicException(@NotNull String message, @Nullable String schematicName) {
|
||||||
|
super(message);
|
||||||
|
this.schematicName = schematicName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSchematicName() {
|
||||||
|
return schematicName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
package me.youhavetrouble.blockedit.exception;
|
||||||
|
|
||||||
|
import me.youhavetrouble.blockedit.schematic.SchematicProvider;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class SchematicHandlerRegistrationException extends IllegalArgumentException {
|
||||||
|
|
||||||
|
private final SchematicProvider<?> schematicProvider;
|
||||||
|
|
||||||
|
public SchematicHandlerRegistrationException(
|
||||||
|
@NotNull String message,
|
||||||
|
@Nullable SchematicProvider<?> schematicProvider
|
||||||
|
) {
|
||||||
|
super(message);
|
||||||
|
this.schematicProvider = schematicProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public SchematicProvider<?> getSchematicProvider() {
|
||||||
|
return schematicProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,9 +1,16 @@
|
|||||||
package me.youhavetrouble.blockedit.exception;
|
package me.youhavetrouble.blockedit.exception;
|
||||||
|
|
||||||
public class SchematicLoadException extends RuntimeException {
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public SchematicLoadException(String message) {
|
public class SchematicLoadException extends SchematicException {
|
||||||
super(message);
|
|
||||||
|
public SchematicLoadException(@NotNull String message, @NotNull String schematicName, @Nullable Throwable cause) {
|
||||||
|
super(message, schematicName, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SchematicLoadException(@NotNull String message, @NotNull String schematicName) {
|
||||||
|
super(message, schematicName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package me.youhavetrouble.blockedit.exception;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class SchematicSaveException extends SchematicException {
|
||||||
|
|
||||||
|
public SchematicSaveException(@NotNull String message, @NotNull String schematicName, Throwable cause) {
|
||||||
|
super(message, schematicName, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SchematicSaveException(@NotNull String message, @NotNull String schematicName) {
|
||||||
|
super(message, schematicName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package me.youhavetrouble.blockedit.schematic;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public interface FileSchematicProvider<S extends Schematic> extends SchematicProvider<S> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the file extensions of the schematic provider.
|
||||||
|
*/
|
||||||
|
@NotNull String[] fileExtensions();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,10 +15,7 @@ public interface SchematicProvider<S extends Schematic> {
|
|||||||
*/
|
*/
|
||||||
@NotNull String name();
|
@NotNull String name();
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the file extensions of the schematic provider.
|
|
||||||
*/
|
|
||||||
@NotNull String[] fileExtensions();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the schematic
|
* Save the schematic
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package me.youhavetrouble.blockedit.util;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NameFilenameFilter implements FilenameFilter {
|
||||||
|
|
||||||
|
private final String filterName;
|
||||||
|
|
||||||
|
public NameFilenameFilter(@NotNull String name) {
|
||||||
|
this.filterName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accept(File dir, String name) {
|
||||||
|
|
||||||
|
String[] parts = name.split("\\.");
|
||||||
|
if (parts.length < 2) return filterName.equals(name);
|
||||||
|
String joined = String.join(".", List.of(parts).subList(0, parts.length - 1));
|
||||||
|
return joined.equals(filterName);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user