package com.xfestudio.xfeservermanager.core.spi;
import com.xfestudio.xfeservermanager.api.command.CommandAnalysisRequest;
import com.xfestudio.xfeservermanager.api.command.InvocationAst;
import com.xfestudio.xfeservermanager.api.spi.CommandSemanticAdapter;
import com.xfestudio.xfeservermanager.api.spi.SemanticAnalysisException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.ServiceLoader;
/** Deterministic dispatcher for built-in and service-loaded semantic adapters. */
public final class CommandSemanticRegistry {
private static final Comparator<CommandSemanticAdapter> ORDER = Comparator
.comparingInt(CommandSemanticAdapter::priority).reversed()
.thenComparing(adapter -> adapter.getClass().getName());
private final List<CommandSemanticAdapter> adapters;
public CommandSemanticRegistry(Collection<? extends CommandSemanticAdapter> adapters) {
this.adapters = adapters.stream().sorted(ORDER).map(adapter -> (CommandSemanticAdapter) adapter).toList();
}
public static CommandSemanticRegistry discover(ClassLoader classLoader) {
List<CommandSemanticAdapter> discovered = new ArrayList<>();
ServiceLoader.load(CommandSemanticAdapter.class, classLoader).forEach(discovered::add);
return new CommandSemanticRegistry(discovered);
}
public Optional<InvocationAst> analyze(CommandAnalysisRequest request) throws SemanticAnalysisException {
for (CommandSemanticAdapter adapter : adapters) {
if (!adapter.supports(request.commandId())) {
continue;
}
Optional<InvocationAst> result = adapter.analyze(request);
if (result.isPresent()) {
InvocationAst invocation = result.orElseThrow();
if (!invocation.commandId().equals(request.commandId())) {
throw new SemanticAnalysisException("Adapter " + adapter.getClass().getName()
+ " returned a different command id");
}
if (!invocation.semanticsKnown()) {
throw new SemanticAnalysisException("Semantic adapters must mark successful analysis as known");
}
return result;
}
}
return Optional.empty();
}
public List<CommandSemanticAdapter> adapters() {
return adapters;
}
}
package com.xfestudio.xfeservermanager.core.spi;
import com.xfestudio.xfeservermanager.api.command.CommandAnalysisRequest;
import com.xfestudio.xfeservermanager.api.command.InvocationAst;
import com.xfestudio.xfeservermanager.api.spi.CommandSemanticAdapter;
import com.xfestudio.xfeservermanager.api.spi.SemanticAnalysisException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.ServiceLoader;
/** Deterministic dispatcher for built-in and service-loaded semantic adapters. */
public final class CommandSemanticRegistry {
private static final Comparator<CommandSemanticAdapter> ORDER = Comparator
.comparingInt(CommandSemanticAdapter::priority).reversed()
.thenComparing(adapter -> adapter.getClass().getName());
private final List<CommandSemanticAdapter> adapters;
public CommandSemanticRegistry(Collection<? extends CommandSemanticAdapter> adapters) {
this.adapters = adapters.stream().sorted(ORDER).map(adapter -> (CommandSemanticAdapter) adapter).toList();
}
public static CommandSemanticRegistry discover(ClassLoader classLoader) {
List<CommandSemanticAdapter> discovered = new ArrayList<>();
ServiceLoader.load(CommandSemanticAdapter.class, classLoader).forEach(discovered::add);
return new CommandSemanticRegistry(discovered);
}
public Optional<InvocationAst> analyze(CommandAnalysisRequest request) throws SemanticAnalysisException {
for (CommandSemanticAdapter adapter : adapters) {
if (!adapter.supports(request.commandId())) {
continue;
}
Optional<InvocationAst> result = adapter.analyze(request);
if (result.isPresent()) {
InvocationAst invocation = result.orElseThrow();
if (!invocation.commandId().equals(request.commandId())) {
throw new SemanticAnalysisException("Adapter " + adapter.getClass().getName()
+ " returned a different command id");
}
if (!invocation.semanticsKnown()) {
throw new SemanticAnalysisException("Semantic adapters must mark successful analysis as known");
}
return result;
}
}
return Optional.empty();
}
public List<CommandSemanticAdapter> adapters() {
return adapters;
}
}