diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/NewParamsRestResource.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/NewParamsRestResource.java index fcb4aa7203ca0..b9e57109a60a9 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/NewParamsRestResource.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/NewParamsRestResource.java @@ -49,10 +49,16 @@ public String params(@RestPath String p, @RestQuery Optional q2, @RestQuery Optional q3, @RestHeader int h, + @RestHeader String xMyHeader, + @RestHeader("Test-Header-Param") String testHeaderParam, + @RestHeader("") String paramEmpty, @RestForm String f, @RestMatrix String m, @RestCookie String c) { - return "params: p: " + p + ", q: " + q + ", h: " + h + ", f: " + f + ", m: " + m + ", c: " + c + ", q2: " + return "params: p: " + p + ", q: " + q + ", h: " + h + ", xMyHeader: " + xMyHeader + ", testHeaderParam: " + + testHeaderParam + ", paramEmpty: " + + paramEmpty + ", f: " + f + ", m: " + m + ", c: " + + c + ", q2: " + q2.orElse("empty") + ", q3: " + q3.orElse(-1); } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/SimpleQuarkusRestTestCase.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/SimpleQuarkusRestTestCase.java index 0af962e3c270f..ece6f57e522ce 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/SimpleQuarkusRestTestCase.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/simple/SimpleQuarkusRestTestCase.java @@ -385,11 +385,16 @@ public void testNewParams() { .queryParam("q", "qv") .queryParam("q3", "999") .header("h", "123") + .header("X-My-Header", "test") + .header("Test-Header-Param", "test") + .header("Param-Empty", "empty") .formParam("f", "fv") .post("/new-params/myklass;m=mv/myregex/params/pv") .then() .log().ifError() - .body(Matchers.equalTo("params: p: pv, q: qv, h: 123, f: fv, m: mv, c: cv, q2: empty, q3: 999")); + .body(Matchers + .equalTo( + "params: p: pv, q: qv, h: 123, xMyHeader: test, testHeaderParam: test, paramEmpty: empty, f: fv, m: mv, c: cv, q2: empty, q3: 999")); RestAssured.get("/new-params/myklass/myregex/sse") .then() .log().ifError() diff --git a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java index 70e3f261bc81b..fd0f82d90f548 100644 --- a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java +++ b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java @@ -822,7 +822,11 @@ public PARAM extractParameterInfo(ClassInfo currentClassInfo, ClassInfo actualEn builder.setType(ParameterType.HEADER); convertible = true; } else if (restHeaderParam != null) { - builder.setName(valueOrDefault(restHeaderParam.value(), sourceName)); + if (restHeaderParam.value() == null || restHeaderParam.value().asString().isEmpty()) { + builder.setName(StringUtil.hyphenate(sourceName)); + } else { + builder.setName(restHeaderParam.value().asString()); + } builder.setType(ParameterType.HEADER); convertible = true; } else if (formParam != null) { diff --git a/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/StringUtil.java b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/StringUtil.java new file mode 100644 index 0000000000000..2898c52a40aef --- /dev/null +++ b/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/StringUtil.java @@ -0,0 +1,85 @@ +package org.jboss.resteasy.reactive.common.processor; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class StringUtil { + + public static Iterator camelHumpsIterator(final String str) { + return new Iterator() { + int idx; + + public boolean hasNext() { + return idx < str.length(); + } + + public String next() { + if (idx == str.length()) + throw new NoSuchElementException(); + // known mixed-case rule-breakers + if (str.startsWith("JBoss", idx)) { + idx += 5; + return "JBoss"; + } + final int start = idx; + int c = str.codePointAt(idx); + if (Character.isUpperCase(c)) { + // an uppercase-starting word + idx = str.offsetByCodePoints(idx, 1); + if (idx < str.length()) { + c = str.codePointAt(idx); + if (Character.isUpperCase(c)) { + // all-caps word; need one look-ahead + int nextIdx = str.offsetByCodePoints(idx, 1); + while (nextIdx < str.length()) { + c = str.codePointAt(nextIdx); + if (Character.isLowerCase(c)) { + // ended at idx + return str.substring(start, idx); + } + idx = nextIdx; + nextIdx = str.offsetByCodePoints(idx, 1); + } + // consumed the whole remainder, update idx to length + idx = str.length(); + return str.substring(start); + } else { + // initial caps, trailing lowercase + idx = str.offsetByCodePoints(idx, 1); + while (idx < str.length()) { + c = str.codePointAt(idx); + if (Character.isUpperCase(c)) { + // end + return str.substring(start, idx); + } + idx = str.offsetByCodePoints(idx, 1); + } + // consumed the whole remainder + return str.substring(start); + } + } else { + // one-letter word + return str.substring(start); + } + } else { + // a lowercase-starting word + idx = str.offsetByCodePoints(idx, 1); + while (idx < str.length()) { + c = str.codePointAt(idx); + if (Character.isUpperCase(c)) { + // end + return str.substring(start, idx); + } + idx = str.offsetByCodePoints(idx, 1); + } + // consumed the whole remainder + return str.substring(start); + } + } + }; + } + + public static String hyphenate(final String orig) { + return String.join("-", (Iterable) () -> camelHumpsIterator(orig)); + } +} \ No newline at end of file