Skip to content

Commit 332af62

Browse files
committed
Introduced McpServiceLoader class to handle all types of service loading
in common way.
1 parent 28edf65 commit 332af62

File tree

3 files changed

+95
-44
lines changed

3 files changed

+95
-44
lines changed
Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,27 @@
11
package io.modelcontextprotocol.json.internal;
22

3-
import java.util.Optional;
4-
import java.util.ServiceConfigurationError;
5-
import java.util.ServiceLoader;
6-
73
import io.modelcontextprotocol.json.McpJsonMapper;
84
import io.modelcontextprotocol.json.McpJsonMapperSupplier;
5+
import io.modelcontextprotocol.util.McpServiceLoader;
96

107
public class DefaultMcpJsonMapperSupplier {
118

12-
private static McpJsonMapperSupplier jsonMapperSupplier;
9+
private static McpServiceLoader<McpJsonMapperSupplier, McpJsonMapper> mcpServiceLoader;
1310

14-
private static McpJsonMapper defaultJsonMapper;
11+
public DefaultMcpJsonMapperSupplier() {
12+
mcpServiceLoader = new McpServiceLoader<McpJsonMapperSupplier, McpJsonMapper>();
13+
}
1514

1615
void setMcpJsonMapperSupplier(McpJsonMapperSupplier supplier) {
17-
jsonMapperSupplier = supplier;
16+
mcpServiceLoader.setSupplier(supplier);
1817
}
1918

2019
void unsetMcpJsonMapperSupplier(McpJsonMapperSupplier supplier) {
21-
jsonMapperSupplier = null;
22-
defaultJsonMapper = null;
20+
mcpServiceLoader.unsetSupplier(supplier);
2321
}
2422

2523
public synchronized static McpJsonMapper getDefaultMcpJsonMapper() {
26-
if (defaultJsonMapper == null) {
27-
if (jsonMapperSupplier == null) {
28-
// Use serviceloader
29-
Optional<McpJsonMapperSupplier> sl = ServiceLoader.load(McpJsonMapperSupplier.class).findFirst();
30-
if (sl.isEmpty()) {
31-
throw new ServiceConfigurationError("No JsonMapperSupplier available for creating McpJsonMapper");
32-
}
33-
jsonMapperSupplier = sl.get();
34-
}
35-
defaultJsonMapper = jsonMapperSupplier.get();
36-
}
37-
return defaultJsonMapper;
24+
return mcpServiceLoader.getDefault();
3825
}
3926

4027
}
Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,27 @@
11
package io.modelcontextprotocol.json.internal;
22

3-
import java.util.Optional;
4-
import java.util.ServiceConfigurationError;
5-
import java.util.ServiceLoader;
6-
73
import io.modelcontextprotocol.json.schema.JsonSchemaValidator;
84
import io.modelcontextprotocol.json.schema.JsonSchemaValidatorSupplier;
5+
import io.modelcontextprotocol.util.McpServiceLoader;
96

107
public class DefaultMcpJsonSchemaValidatorSupplier {
118

12-
private static JsonSchemaValidatorSupplier jsonSchemaValidatorSupplier;
9+
private static McpServiceLoader<JsonSchemaValidatorSupplier, JsonSchemaValidator> mcpServiceLoader;
1310

14-
private static JsonSchemaValidator defaultJsonSchemaValidator;
11+
public DefaultMcpJsonSchemaValidatorSupplier() {
12+
mcpServiceLoader = new McpServiceLoader<JsonSchemaValidatorSupplier, JsonSchemaValidator>();
13+
}
1514

1615
void setJsonSchemaValidatorSupplier(JsonSchemaValidatorSupplier supplier) {
17-
jsonSchemaValidatorSupplier = supplier;
16+
mcpServiceLoader.setSupplier(supplier);
1817
}
1918

2019
void unsetJsonSchemaValidatorSupplier(JsonSchemaValidatorSupplier supplier) {
21-
jsonSchemaValidatorSupplier = null;
22-
defaultJsonSchemaValidator = null;
20+
mcpServiceLoader.unsetSupplier(supplier);
2321
}
2422

2523
public synchronized static JsonSchemaValidator getDefaultJsonSchemaValidator() {
26-
if (defaultJsonSchemaValidator == null) {
27-
if (jsonSchemaValidatorSupplier == null) {
28-
// Use serviceloader
29-
Optional<JsonSchemaValidatorSupplier> sl = ServiceLoader.load(JsonSchemaValidatorSupplier.class)
30-
.findFirst();
31-
if (sl.isEmpty()) {
32-
throw new ServiceConfigurationError(
33-
"No JsonSchemaValidatorSupplier available for creating JsonSchemaValidator");
34-
}
35-
jsonSchemaValidatorSupplier = sl.get();
36-
}
37-
defaultJsonSchemaValidator = jsonSchemaValidatorSupplier.get();
38-
}
39-
return defaultJsonSchemaValidator;
24+
return mcpServiceLoader.getDefault();
4025
}
4126

4227
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package io.modelcontextprotocol.util;
2+
3+
import java.lang.reflect.ParameterizedType;
4+
import java.lang.reflect.Type;
5+
import java.util.Optional;
6+
import java.util.ServiceConfigurationError;
7+
import java.util.ServiceLoader;
8+
import java.util.function.Supplier;
9+
10+
public class McpServiceLoader<S extends Supplier<R>, R> {
11+
12+
private Type supplierType;
13+
14+
private S supplier;
15+
16+
private R supplierResult;
17+
18+
protected abstract class TypeToken<T> {
19+
20+
private Type type;
21+
22+
protected TypeToken() {
23+
Type superClass = getClass().getGenericSuperclass();
24+
this.type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
25+
}
26+
27+
public Type getType() {
28+
return type;
29+
}
30+
31+
}
32+
33+
protected class SupplierTypeToken extends TypeToken<S> {
34+
35+
};
36+
37+
public void setSupplier(S supplier) {
38+
this.supplier = supplier;
39+
this.supplierResult = null;
40+
}
41+
42+
public void unsetSupplier(S supplier) {
43+
this.supplier = null;
44+
this.supplierResult = null;
45+
}
46+
47+
public McpServiceLoader() {
48+
this.supplierType = new SupplierTypeToken().getType();
49+
}
50+
51+
protected Optional<S> serviceLoad(Class<S> type) {
52+
return ServiceLoader.load(type).findFirst();
53+
}
54+
55+
@SuppressWarnings("unchecked")
56+
public synchronized R getDefault() {
57+
if (this.supplierResult == null) {
58+
if (this.supplier == null) {
59+
// Use serviceloader
60+
Optional<?> sl;
61+
try {
62+
sl = serviceLoad((Class<S>) Class.forName(this.supplierType.getTypeName()));
63+
if (sl.isEmpty()) {
64+
throw new ServiceConfigurationError(
65+
"No JsonMapperSupplier available for creating McpJsonMapper");
66+
}
67+
}
68+
catch (ClassNotFoundException e) {
69+
throw new ServiceConfigurationError(
70+
"ClassNotFoundException for Type=" + this.supplierType.getTypeName());
71+
}
72+
this.supplier = (S) sl.get();
73+
}
74+
this.supplierResult = this.supplier.get();
75+
}
76+
return supplierResult;
77+
}
78+
79+
}

0 commit comments

Comments
 (0)