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;
|
||||
|
||||
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.SchematicProvider;
|
||||
import me.youhavetrouble.blockedit.util.Clipboard;
|
||||
import me.youhavetrouble.blockedit.util.NameFilenameFilter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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>> schematicProvidersByName = new HashMap<>();
|
||||
|
||||
private final File schematicsDirectory;
|
||||
public final File schematicsDirectory;
|
||||
|
||||
protected SchematicHandler(BlockEdit plugin) {
|
||||
this.plugin = plugin;
|
||||
@@ -35,40 +40,53 @@ public class SchematicHandler<S extends Schematic> {
|
||||
|
||||
public void registerSchematicProvider(
|
||||
@NotNull SchematicProvider<S> schematicProvider
|
||||
) throws IllegalArgumentException {
|
||||
if (!schematicProvider.name().matches("^[a-z0-9]+$")) {
|
||||
throw new IllegalArgumentException("Schematic provider name can only contain lowercase letters and numbers");
|
||||
) throws SchematicHandlerRegistrationException {
|
||||
|
||||
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())) {
|
||||
throw new IllegalArgumentException("Schematic provider " + schematicProvider.name() + " is already registered");
|
||||
if (schematicProvidersByName.containsKey(schematicProviderName)) {
|
||||
throw new SchematicHandlerRegistrationException("Schematic provider with name " + schematicProvider.name() + " is already registered", schematicProvider);
|
||||
}
|
||||
|
||||
// Register the provider as a file provider that associates the provider with file extensions
|
||||
if (schematicProvider instanceof FileSchematicProvider<S> fileSchematicProvider) {
|
||||
// Loop extensions to verify if they're valid and not already registered
|
||||
for (String extension : schematicProvider.fileExtensions()) {
|
||||
for (String extension : fileSchematicProvider.fileExtensions()) {
|
||||
String trimmedExtension = extension.trim();
|
||||
if (trimmedExtension.isEmpty()) throw new IllegalArgumentException("File extension cannot be empty");
|
||||
if (!trimmedExtension.matches("^[a-z0-9]+$")) throw new IllegalArgumentException("File extension can only contain lowercase letters and numbers");
|
||||
if (trimmedExtension.isEmpty()) throw new SchematicHandlerRegistrationException("File extension cannot be empty", fileSchematicProvider);
|
||||
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 IllegalArgumentException("File extension " + trimmedExtension + " is already registered to " + schematicProvidersByExtension.get(trimmedExtension).name());
|
||||
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 : schematicProvider.fileExtensions()) {
|
||||
for (String extension : fileSchematicProvider.fileExtensions()) {
|
||||
String trimmedExtension = extension.trim();
|
||||
schematicProvidersByExtension.put(trimmedExtension, schematicProvider);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
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 schematicName Name of the schematic
|
||||
* @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);
|
||||
if (schematicProvider == null) {
|
||||
throw new IllegalArgumentException("Schematic provider " + providerName + " is not registered");
|
||||
@@ -76,6 +94,34 @@ public class SchematicHandler<S extends Schematic> {
|
||||
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
|
||||
* @param schematicName Name of the schematic
|
||||
@@ -85,15 +131,13 @@ public class SchematicHandler<S extends Schematic> {
|
||||
@NotNull String schematicName,
|
||||
@NotNull String providerName,
|
||||
@NotNull Clipboard clipboard
|
||||
) {
|
||||
) throws SchematicSaveException {
|
||||
SchematicProvider<S> schematicProvider = schematicProvidersByName.get(providerName);
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
public class SchematicLoadException extends RuntimeException {
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public SchematicLoadException(String message) {
|
||||
super(message);
|
||||
public class SchematicLoadException extends SchematicException {
|
||||
|
||||
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();
|
||||
|
||||
/**
|
||||
* Get the file extensions of the schematic provider.
|
||||
*/
|
||||
@NotNull String[] fileExtensions();
|
||||
|
||||
|
||||
/**
|
||||
* 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