Skip to content

Commit 6ec7b65

Browse files
committed
- remove duplicated code while parsing McpResourceAnnotation
1 parent 352923a commit 6ec7b65

2 files changed

Lines changed: 54 additions & 51 deletions

File tree

modules/jooby-apt/src/main/java/io/jooby/internal/apt/McpRoute.java

Lines changed: 53 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import java.util.ArrayList;
1212
import java.util.List;
13+
import java.util.Map;
1314

1415
import javax.lang.model.element.ExecutableElement;
1516

@@ -435,14 +436,8 @@ public List<String> generateMcpDefinitionMethod(boolean kt) {
435436
String sizeArg = (sizeStr.isEmpty() || sizeStr.equals("-1")) ? "null" : sizeStr + "L";
436437

437438
// --- NESTED ANNOTATION EXTRACTION ---
438-
// We parse the string representation of the annotation to avoid massive APT ElementVisitor
439-
// boilerplate.
440-
// It looks like: @...McpAnnotations(audience={"USER"}, priority=1.0, lastModified="2024")
441439
String annotationsArg = "null";
442-
String rawAnnotations =
443-
extractAnnotationValue("io.jooby.annotation.mcp.McpResource", "annotations");
444-
445-
boolean hasAnnotations = rawAnnotations.contains("priority=");
440+
var annotation = parseResourceAnnotation();
446441

447442
var isTemplate = isMcpResourceTemplate();
448443
var specType = isTemplate ? "ResourceTemplate" : "Resource";
@@ -459,32 +454,15 @@ public List<String> generateMcpDefinitionMethod(boolean kt) {
459454
" {"));
460455

461456
// Build the Kotlin ResourceAnnotations object if present
462-
if (hasAnnotations) {
463-
annotationsArg = "annotations";
464-
String audienceList =
465-
rawAnnotations.contains("USER") && rawAnnotations.contains("ASSISTANT")
466-
? "listOf(io.modelcontextprotocol.spec.McpSchema.Role.USER,"
467-
+ " io.modelcontextprotocol.spec.McpSchema.Role.ASSISTANT)"
468-
: (rawAnnotations.contains("USER")
469-
? "listOf(io.modelcontextprotocol.spec.McpSchema.Role.USER)"
470-
: (rawAnnotations.contains("ASSISTANT")
471-
? "listOf(io.modelcontextprotocol.spec.McpSchema.Role.ASSISTANT)"
472-
: "emptyList()"));
473-
474-
String priority = rawAnnotations.replaceAll(".*priority=([0-9.]+).*", "$1");
475-
var lastMod =
476-
rawAnnotations.contains("lastModified=")
477-
? string(rawAnnotations.replaceAll(".*lastModified=\"([^\"]+)\".*", "$1"))
478-
: "null";
479-
480-
buffer.add(statement(indent(6), "val audience = ", audienceList));
457+
if (annotation != null) {
458+
buffer.add(statement(indent(6), "val audience = ", "listOf(", annotation.audience, ""));
481459
buffer.add(
482460
statement(
483461
indent(6),
484462
"val annotations = io.modelcontextprotocol.spec.McpSchema.Annotations(audience, ",
485-
priority,
463+
annotation.priority,
486464
", ",
487-
lastMod,
465+
annotation.lastModified,
488466
")"));
489467
}
490468

@@ -539,33 +517,25 @@ public List<String> generateMcpDefinitionMethod(boolean kt) {
539517
"Spec() {"));
540518

541519
// Build the Java ResourceAnnotations object if present
542-
if (hasAnnotations) {
520+
if (annotation != null) {
543521
annotationsArg = "annotations";
544-
String audienceList =
545-
rawAnnotations.contains("USER") && rawAnnotations.contains("ASSISTANT")
546-
? "java.util.List.of(io.modelcontextprotocol.spec.McpSchema.Role.USER,"
547-
+ " io.modelcontextprotocol.spec.McpSchema.Role.ASSISTANT)"
548-
: (rawAnnotations.contains("USER")
549-
? "java.util.List.of(io.modelcontextprotocol.spec.McpSchema.Role.USER)"
550-
: (rawAnnotations.contains("ASSISTANT")
551-
? "java.util.List.of(io.modelcontextprotocol.spec.McpSchema.Role.ASSISTANT)"
552-
: "java.util.Collections.emptyList()"));
553-
554-
String priority = rawAnnotations.replaceAll(".*priority=([0-9.]+).*", "$1");
555-
var lastMod =
556-
rawAnnotations.contains("lastModified=")
557-
? string(rawAnnotations.replaceAll(".*lastModified=\"([^\"]+)\".*", "$1"))
558-
: "null";
559-
560-
buffer.add(statement(indent(6), "var audience = ", audienceList, semicolon(kt)));
522+
523+
buffer.add(
524+
statement(
525+
indent(6),
526+
"var audience = ",
527+
"java.util.List.of(",
528+
annotation.audience,
529+
")",
530+
semicolon(kt)));
561531
buffer.add(
562532
statement(
563533
indent(6),
564534
"var annotations = new"
565535
+ " io.modelcontextprotocol.spec.McpSchema.Annotations(audience, ",
566-
priority,
536+
annotation.priority,
567537
"D, ",
568-
lastMod,
538+
annotation.lastModified,
569539
")",
570540
semicolon(kt)));
571541
}
@@ -940,5 +910,39 @@ private boolean hasOutputSchema() {
940910
&& !isMcpClass;
941911
}
942912

943-
private record McpAnnotation(String name, String value) {}
913+
private McpAnnotation parseResourceAnnotation() {
914+
String rawAnnotations =
915+
extractAnnotationValue("io.jooby.annotation.mcp.McpResource", "annotations");
916+
917+
boolean hasAnnotations = rawAnnotations.contains("priority=");
918+
919+
if (!hasAnnotations) {
920+
return null;
921+
}
922+
923+
var audienceList = new ArrayList<String>();
924+
var annotationMap =
925+
Map.of(
926+
"USER",
927+
"io.modelcontextprotocol.spec.McpSchema.Role.USER",
928+
"ASSISTANT",
929+
"io.modelcontextprotocol.spec.McpSchema.Role.ASSISTANT");
930+
for (var entry : annotationMap.entrySet()) {
931+
if (rawAnnotations.contains(entry.getKey())) {
932+
audienceList.add(entry.getValue());
933+
}
934+
}
935+
if (audienceList.isEmpty()) {
936+
audienceList.add(annotationMap.get("USER"));
937+
}
938+
var priority = rawAnnotations.replaceAll(".*priority=([0-9.]+).*", "$1");
939+
var lastMod =
940+
rawAnnotations.contains("lastModified=")
941+
? string(rawAnnotations.replaceAll(".*lastModified=\"([^\"]+)\".*", "$1"))
942+
: "null";
943+
944+
return new McpAnnotation(String.join(", ", audienceList), lastMod.toString(), priority);
945+
}
946+
947+
private record McpAnnotation(String audience, String lastModified, String priority) {}
944948
}

modules/jooby-mcp/src/main/java/io/jooby/annotation/mcp/McpResource.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@
5656
int size() default -1;
5757

5858
/** Optional MCP metadata annotations for this resource. */
59-
McpAnnotations[]
60-
annotations() default {}; // Using an array is the safest way to provide an "empty" default in
59+
McpAnnotations[] annotations() default {};
6160

6261
@Retention(RetentionPolicy.RUNTIME)
6362
@Target(ElementType.ANNOTATION_TYPE)

0 commit comments

Comments
 (0)