From bf73e7df9ea9b96d0b93505b8994266d3a0d5773 Mon Sep 17 00:00:00 2001 From: Jesenko Mehmedbasic Date: Tue, 10 Oct 2023 13:04:53 +0200 Subject: [PATCH 01/11] The project builds and runs tests with both JDK 11 and JDK 17 --- examples/full-api-edge-cases/pom.xml | 5 +++++ examples/jackson2-api-lombok/pom.xml | 5 +++++ examples/jackson2-api/pom.xml | 5 +++++ examples/spring-petclinic/pom.xml | 5 +++++ pom.xml | 1 + rt-util/pom.xml | 1 + 6 files changed, 22 insertions(+) diff --git a/examples/full-api-edge-cases/pom.xml b/examples/full-api-edge-cases/pom.xml index 5998df174..ea06decd5 100644 --- a/examples/full-api-edge-cases/pom.xml +++ b/examples/full-api-edge-cases/pom.xml @@ -15,6 +15,11 @@ + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + org.apache.maven.plugins maven-surefire-plugin diff --git a/examples/jackson2-api-lombok/pom.xml b/examples/jackson2-api-lombok/pom.xml index 4392658fd..227518fb7 100644 --- a/examples/jackson2-api-lombok/pom.xml +++ b/examples/jackson2-api-lombok/pom.xml @@ -15,6 +15,11 @@ + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + com.webcohesion.enunciate enunciate-maven-plugin diff --git a/examples/jackson2-api/pom.xml b/examples/jackson2-api/pom.xml index 96a7a027f..80e28ac18 100644 --- a/examples/jackson2-api/pom.xml +++ b/examples/jackson2-api/pom.xml @@ -15,6 +15,11 @@ + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + com.webcohesion.enunciate enunciate-maven-plugin diff --git a/examples/spring-petclinic/pom.xml b/examples/spring-petclinic/pom.xml index ca5adde07..c0f906344 100644 --- a/examples/spring-petclinic/pom.xml +++ b/examples/spring-petclinic/pom.xml @@ -21,6 +21,11 @@ + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + com.webcohesion.enunciate enunciate-maven-plugin diff --git a/pom.xml b/pom.xml index 464fea744..518f16ead 100644 --- a/pom.xml +++ b/pom.xml @@ -132,6 +132,7 @@ 3.3.0 3.3.0 1.6.0 + 3.3.2 https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HXSXBXUT63RCG diff --git a/rt-util/pom.xml b/rt-util/pom.xml index 093d4a3c9..c2a7a41a8 100644 --- a/rt-util/pom.xml +++ b/rt-util/pom.xml @@ -59,6 +59,7 @@ org.mockito mockito-core + 5.6.0 test From c5a105ae4318d3e155e6f6d76661a5ca13339fb4 Mon Sep 17 00:00:00 2001 From: Jesenko Mehmedbasic Date: Tue, 10 Oct 2023 15:29:26 +0200 Subject: [PATCH 02/11] Include java-11 compatible checks for java.lang.Record --- .../enunciate/util/AccessorBag.java | 2 +- .../jackson/EnunciateJacksonContext.java | 1 - .../jackson/model/ObjectTypeDefinition.java | 4 +-- .../modules/jackson/model/TypeDefinition.java | 31 +++++++++++++++++-- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/webcohesion/enunciate/util/AccessorBag.java b/core/src/main/java/com/webcohesion/enunciate/util/AccessorBag.java index 1e5510267..20da06078 100644 --- a/core/src/main/java/com/webcohesion/enunciate/util/AccessorBag.java +++ b/core/src/main/java/com/webcohesion/enunciate/util/AccessorBag.java @@ -40,7 +40,7 @@ public void removeByName(E memberDeclaration) { } } - public final ElementList fields = new ElementList<>(); + public final ElementList fields = new ElementList<>(); public final ElementList properties = new ElementList<>(); public String typeIdProperty; diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java index c4e338b16..bdb046c3e 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java @@ -35,7 +35,6 @@ import com.webcohesion.enunciate.metadata.rs.TypeHint; import com.webcohesion.enunciate.module.EnunciateModuleContext; import com.webcohesion.enunciate.modules.jackson.javac.InterfaceJacksonDeclaredType; -import com.webcohesion.enunciate.modules.jackson.javac.InterfaceJacksonTypeElement; import com.webcohesion.enunciate.modules.jackson.javac.ParameterizedJacksonDeclaredType; import com.webcohesion.enunciate.modules.jackson.javac.SyntheticJacksonArrayType; import com.webcohesion.enunciate.modules.jackson.model.*; diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/ObjectTypeDefinition.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/ObjectTypeDefinition.java index 0bf4745b1..2a5753841 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/ObjectTypeDefinition.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/ObjectTypeDefinition.java @@ -43,7 +43,7 @@ public JsonType getSupertype() { if (superclass == null || superclass.getKind() == TypeKind.NONE) { return null; } - else if (superclass instanceof DeclaredType && (((TypeElement)((DeclaredType)superclass).asElement()).getQualifiedName().toString().equals(Object.class.getName()) || ((TypeElement)((DeclaredType)superclass).asElement()).getQualifiedName().toString().equals(Record.class.getName()) || context.isIgnored((((DeclaredType)superclass).asElement())) || context.isCollapseTypeHierarchy())) { + else if (superclass instanceof DeclaredType && (((TypeElement)((DeclaredType)superclass).asElement()).getQualifiedName().toString().equals(Object.class.getName()) || ((TypeElement)((DeclaredType)superclass).asElement()).getQualifiedName().toString().equals("java.lang.Record") || context.isIgnored((((DeclaredType)superclass).asElement())) || context.isCollapseTypeHierarchy())) { return null; } else { @@ -72,7 +72,7 @@ public boolean isBaseObject() { return superDeclaration == null || Object.class.getName().equals(superDeclaration.getQualifiedName().toString()) || Enum.class.getName().equals(superDeclaration.getQualifiedName().toString()) - || Record.class.getName().equals(superDeclaration.getQualifiedName().toString()) + || "java.lang.Record".equals(superDeclaration.getQualifiedName().toString()) || this.context.isCollapseTypeHierarchy() || this.context.isIgnored(superDeclaration); } diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java index c6437eda5..4a6bce766 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java @@ -42,6 +42,7 @@ import jakarta.xml.bind.annotation.XmlType; import java.lang.annotation.Annotation; +import java.lang.reflect.Method; import java.util.*; import java.util.function.Function; @@ -191,7 +192,7 @@ protected AccessorBag loadPotentialAccessors(AccessorFilter filter) { */ protected void aggregatePotentialAccessors(AccessorBag bag, DecoratedTypeElement clazz, AccessorFilter filter, boolean inlineAccessorsOfSuperclasses) { String fqn = clazz.getQualifiedName().toString(); - if (Object.class.getName().equals(fqn) || Enum.class.getName().equals(fqn)) { + if (Object.class.getName().equals(fqn) || Enum.class.getName().equals(fqn) || "java.lang.Record".equals(fqn)) { return; } @@ -219,7 +220,7 @@ protected void aggregatePotentialAccessors(AccessorBag bag, DecoratedTypeElement } } - List fieldElements = new ArrayList(ElementFilter.fieldsIn(clazz.getEnclosedElements())); + List fieldElements = new ArrayList<>(extractFieldElements(clazz)); if (mixin != null) { //replace all mixin fields. for (VariableElement mixinField : ElementFilter.fieldsIn(mixin.getEnclosedElements())) { @@ -234,7 +235,7 @@ protected void aggregatePotentialAccessors(AccessorBag bag, DecoratedTypeElement } Set propsIgnore = new HashSet(); - for (VariableElement fieldDeclaration : fieldElements) { + for (Element fieldDeclaration : fieldElements) { JsonUnwrapped unwrapped = fieldDeclaration.getAnnotation(JsonUnwrapped.class); if (unwrapped != null && unwrapped.enabled()) { DecoratedTypeElement element; @@ -327,6 +328,30 @@ else if (!filter.accept(propertyDeclaration) || indexOf(bag.fields, propertyDecl } } + @SuppressWarnings({"unchecked"}) + private static List extractFieldElements(DecoratedTypeElement clazz) { + if (isRecord(clazz)) { + try { + Method method = clazz.getClass().getMethod("getRecordComponents"); + List elements = (List) method.invoke(clazz); + return new ArrayList<>(elements); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + else { + return new ArrayList<>(ElementFilter.fieldsIn(clazz.getEnclosedElements())); + } + } + + private static boolean isRecord(DecoratedTypeElement clazz) { + if (clazz.getSuperclass() == null) { + return false; + } + + return clazz.getSuperclass().toString().equals("java.lang.Record"); + } + protected int indexOf(List accessors, String name) { for (int i = 0; i < accessors.size(); i++) { Element accessor = accessors.get(i); From 5a8398c247c5c7053a79abd6d7a890610d9a1700 Mon Sep 17 00:00:00 2001 From: Jesenko Mehmedbasic Date: Thu, 12 Oct 2023 09:05:54 +0200 Subject: [PATCH 03/11] Enunciate picks up java 16 records as JSON objects --- .../c_client/ClientClassnameForMethod.java | 5 ++- .../enunciate/util/FieldOrRecordUtil.java | 41 +++++++++++++++++++ .../ClientClassnameForMethod.java | 3 +- .../ClientClassnameForMethod.java | 4 +- .../jackson/EnunciateJacksonContext.java | 3 +- .../modules/jackson/JacksonModule.java | 2 +- .../modules/jackson/model/TypeDefinition.java | 33 +++------------ .../jackson/model/types/JsonTypeVisitor.java | 29 +++++++------ .../ClientClassnameForMethod.java | 2 +- .../ClientClassnameForMethod.java | 2 +- .../element/DecoratedTypeElement.java | 7 ++-- .../decorations/type/DecoratedTypeMirror.java | 7 +++- .../ClientClassnameForMethod.java | 3 +- .../modules/jaxb/EnunciateJaxbContext.java | 6 +-- .../enunciate/modules/jaxb/JaxbModule.java | 2 +- .../modules/jaxb/model/Accessor.java | 6 +-- .../jaxb/model/ComplexTypeDefinition.java | 2 +- .../modules/jaxb/model/TypeDefinition.java | 4 +- .../jaxb/model/types/XmlTypeVisitor.java | 28 ++++++------- .../modules/jaxrs/model/Resource.java | 10 +++-- .../jaxrs/model/ResourceParameter.java | 5 ++- .../jaxws/model/EndpointInterface.java | 6 +-- .../objc_client/ClientClassnameForMethod.java | 4 +- .../model/RequestParameterFactory.java | 5 ++- .../spring_web/model/SpringController.java | 2 +- .../model/SpringControllerAdvice.java | 2 +- 26 files changed, 127 insertions(+), 96 deletions(-) create mode 100644 core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java diff --git a/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java b/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java index 2361af1dc..24fdfcb89 100644 --- a/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java +++ b/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java @@ -78,6 +78,7 @@ public ClientClassnameForMethod(Map conversions, EnunciateJaxbCo classConversions.put(javax.xml.datatype.Duration.class.getName(), "xmlChar"); classConversions.put(jakarta.xml.bind.JAXBElement.class.getName(), "struct xmlBasicNode"); classConversions.put(Object.class.getName(), "struct xmlBasicNode"); + classConversions.put("java.lang.Record", "struct xmlBasicNode"); classConversions.putAll(conversions); } @@ -95,7 +96,7 @@ else if (isCollection(declaration)) { if (adapterType != null) { return convert(adapterType.getAdaptingType()); } - if (declaration.getKind() == ElementKind.CLASS) { + if (declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement @@ -194,4 +195,4 @@ public String convert(TypeVariable typeVariable) throws TemplateModelException { return conversion; } -} \ No newline at end of file +} diff --git a/core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java b/core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java new file mode 100644 index 000000000..20d389237 --- /dev/null +++ b/core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java @@ -0,0 +1,41 @@ +package com.webcohesion.enunciate.util; + +import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; + +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.ElementFilter; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +/** + * FieldOrRecordUtil. + */ +public final class FieldOrRecordUtil { + + @SuppressWarnings({"unchecked"}) + public static List extractFieldElements(TypeElement clazz) { + if (isRecord(clazz)) { + try { + Method method = clazz.getClass().getMethod("getRecordComponents"); + List elements = (List) method.invoke(clazz); + return new ArrayList<>(elements); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + else { + return new ArrayList<>(ElementFilter.fieldsIn(clazz.getEnclosedElements())); + } + } + + + private static boolean isRecord(TypeElement clazz) { + if (clazz.getSuperclass() == null) { + return false; + } + + return clazz.getSuperclass().toString().equals("java.lang.Record"); + } +} diff --git a/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java b/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java index 173c5ff84..71fd508ab 100644 --- a/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java +++ b/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java @@ -86,6 +86,7 @@ public ClientClassnameForMethod(Map conversions, EnunciateJaxbCo classConversions.put(javax.xml.datatype.Duration.class.getName(), "TimeSpan?"); classConversions.put(jakarta.xml.bind.JAXBElement.class.getName(), "object"); classConversions.put(Object.class.getName(), "object"); + classConversions.put("java.lang.Record", "object"); } @Override @@ -124,7 +125,7 @@ else if (isCollection(declaration)) { if (adapterType != null) { return convert(adapterType.getAdaptingType()); } - if (declaration.getKind() == ElementKind.CLASS) { + if (declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/gwt-json-overlay/src/main/java/com/webcohesion/enunciate/modules/gwt_json_overlay/ClientClassnameForMethod.java b/gwt-json-overlay/src/main/java/com/webcohesion/enunciate/modules/gwt_json_overlay/ClientClassnameForMethod.java index 56b18ea1f..6b421a657 100644 --- a/gwt-json-overlay/src/main/java/com/webcohesion/enunciate/modules/gwt_json_overlay/ClientClassnameForMethod.java +++ b/gwt-json-overlay/src/main/java/com/webcohesion/enunciate/modules/gwt_json_overlay/ClientClassnameForMethod.java @@ -117,7 +117,7 @@ else if (isCollection(declaration)) { if (adaptingType != null) { return convert(adaptingType); } - if (declaration.getKind() == ElementKind.CLASS) { + if (declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement @@ -202,4 +202,4 @@ else if (decorated.isPrimitive()) { return super.convert(typeMirror); } -} \ No newline at end of file +} diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java index bdb046c3e..c590ba5fb 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java @@ -25,6 +25,7 @@ import com.webcohesion.enunciate.EnunciateContext; import com.webcohesion.enunciate.EnunciateException; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; +import com.webcohesion.enunciate.javac.decorations.SourcePosition; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; import com.webcohesion.enunciate.javac.decorations.element.PropertyElement; import com.webcohesion.enunciate.javac.decorations.type.DecoratedDeclaredType; @@ -225,7 +226,7 @@ protected Map loadKnownTypes() { knownTypes.put(java.net.URI.class.getName(), KnownJsonType.STRING); knownTypes.put(java.net.URL.class.getName(), KnownJsonType.STRING); knownTypes.put(java.lang.Object.class.getName(), KnownJsonType.OBJECT); - knownTypes.put(java.lang.Record.class.getName(), KnownJsonType.OBJECT); + knownTypes.put("java.lang.Record", KnownJsonType.OBJECT); knownTypes.put(java.io.Serializable.class.getName(), KnownJsonType.OBJECT); knownTypes.put(byte[].class.getName(), KnownJsonType.STRING); knownTypes.put(java.nio.ByteBuffer.class.getName(), KnownJsonType.STRING); diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/JacksonModule.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/JacksonModule.java index 0fff3ec53..582135d52 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/JacksonModule.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/JacksonModule.java @@ -216,7 +216,7 @@ protected void addPotentialJacksonElement(Element declaration, LinkedList fieldElements = new ArrayList<>(extractFieldElements(clazz)); + List fieldElements = new ArrayList<>(FieldOrRecordUtil.extractFieldElements(clazz)); if (mixin != null) { //replace all mixin fields. - for (VariableElement mixinField : ElementFilter.fieldsIn(mixin.getEnclosedElements())) { + for (Element mixinField : FieldOrRecordUtil.extractFieldElements(mixin)) { int index = indexOf(fieldElements, mixinField.getSimpleName().toString()); if (index >= 0) { fieldElements.set(index, mixinField); @@ -275,7 +276,7 @@ else if (!filter.accept((DecoratedElement) fieldDeclaration)) { } JacksonPropertySpec propertySpec = new JacksonPropertySpec(this.env); - List propertyElements = new ArrayList(clazz.getProperties(propertySpec)); + List propertyElements = new ArrayList<>(clazz.getProperties(propertySpec)); if (mixin != null) { //replace all mixin properties. for (PropertyElement mixinProperty : ((DecoratedTypeElement)mixin).getProperties(propertySpec)) { @@ -328,30 +329,6 @@ else if (!filter.accept(propertyDeclaration) || indexOf(bag.fields, propertyDecl } } - @SuppressWarnings({"unchecked"}) - private static List extractFieldElements(DecoratedTypeElement clazz) { - if (isRecord(clazz)) { - try { - Method method = clazz.getClass().getMethod("getRecordComponents"); - List elements = (List) method.invoke(clazz); - return new ArrayList<>(elements); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - else { - return new ArrayList<>(ElementFilter.fieldsIn(clazz.getEnclosedElements())); - } - } - - private static boolean isRecord(DecoratedTypeElement clazz) { - if (clazz.getSuperclass() == null) { - return false; - } - - return clazz.getSuperclass().toString().equals("java.lang.Record"); - } - protected int indexOf(List accessors, String name) { for (int i = 0; i < accessors.size(); i++) { Element accessor = accessors.get(i); @@ -625,7 +602,7 @@ public List getAllAccessors() { static DeclaredType refineType(DecoratedProcessingEnvironment env, DecoratedElement element, Class annotation, Function> refiner) { Element elt = element; - while (elt != null && elt.getKind() != ElementKind.CLASS && elt.getKind() != ElementKind.INTERFACE) { + while (elt != null && elt.getKind() != ElementKind.CLASS && elt.getKind() != ElementKind.INTERFACE && !elt.getKind().name().equals("RECORD")) { elt = elt.getEnclosingElement(); } if (elt == null) { diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/types/JsonTypeVisitor.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/types/JsonTypeVisitor.java index b5ff497ba..8fd18b184 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/types/JsonTypeVisitor.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/types/JsonTypeVisitor.java @@ -30,9 +30,11 @@ import com.webcohesion.enunciate.util.TypeHintUtils; import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.lang.model.type.*; import javax.lang.model.util.SimpleTypeVisitor6; +import java.util.Arrays; import java.util.LinkedList; import static com.webcohesion.enunciate.javac.decorations.type.TypeMirrorUtils.getComponentType; @@ -119,22 +121,19 @@ public JsonType visitDeclared(DeclaredType declaredType, Context context) { return wrapAsNeeded(componentType.accept(this, new Context(context.context, false, true, context.stack)), context); } else { - switch (declaredElement.getKind()) { - case ENUM: - case CLASS: - case INTERFACE: - JsonType knownType = context.getContext().getKnownType(declaredElement); - if (knownType != null) { - jsonType = knownType; + String[] kinds = {ElementKind.CLASS.name(), ElementKind.ENUM.name(), ElementKind.INTERFACE.name(), "RECORD"}; + if (Arrays.binarySearch(kinds, declaredElement.getKind().name()) >= 0) { + JsonType knownType = context.getContext().getKnownType(declaredElement); + if (knownType != null) { + jsonType = knownType; + } + else { + //type not known, not specified. Last chance: look for the type definition. + TypeDefinition typeDefinition = context.getContext().findTypeDefinition(declaredElement); + if (typeDefinition != null) { + jsonType = new JsonClassType(typeDefinition); } - else { - //type not known, not specified. Last chance: look for the type definition. - TypeDefinition typeDefinition = context.getContext().findTypeDefinition(declaredElement); - if (typeDefinition != null) { - jsonType = new JsonClassType(typeDefinition); - } - } - break; + } } } } diff --git a/java-json-client/src/main/java/com/webcohesion/enunciate/modules/java_json_client/ClientClassnameForMethod.java b/java-json-client/src/main/java/com/webcohesion/enunciate/modules/java_json_client/ClientClassnameForMethod.java index dfacd5a44..d4597625d 100644 --- a/java-json-client/src/main/java/com/webcohesion/enunciate/modules/java_json_client/ClientClassnameForMethod.java +++ b/java-json-client/src/main/java/com/webcohesion/enunciate/modules/java_json_client/ClientClassnameForMethod.java @@ -94,7 +94,7 @@ public String convert(TypeElement declaration) throws TemplateModelException { if (adaptingType != null) { return convert(adaptingType); } - if (declaration.getKind() == ElementKind.CLASS) { + if (declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/java-xml-client/src/main/java/com/webcohesion/enunciate/modules/java_xml_client/ClientClassnameForMethod.java b/java-xml-client/src/main/java/com/webcohesion/enunciate/modules/java_xml_client/ClientClassnameForMethod.java index 21c9256d2..5a2170a4f 100644 --- a/java-xml-client/src/main/java/com/webcohesion/enunciate/modules/java_xml_client/ClientClassnameForMethod.java +++ b/java-xml-client/src/main/java/com/webcohesion/enunciate/modules/java_xml_client/ClientClassnameForMethod.java @@ -110,7 +110,7 @@ public String convert(TypeElement declaration) throws TemplateModelException { if (adapterType != null) { return convert(adapterType.getAdaptingType()); } - if (declaration.getKind() == ElementKind.CLASS) { + if (declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/DecoratedTypeElement.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/DecoratedTypeElement.java index 0875b4f52..c75c1fcc6 100644 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/DecoratedTypeElement.java +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/DecoratedTypeElement.java @@ -151,7 +151,7 @@ public List enumValues() { public A getAnnotation(Class annotationType) { A annotation = super.getAnnotation(annotationType); - if (isClass() && (annotation == null) && (annotationType.getAnnotation(Inherited.class) != null) && (getSuperclass() instanceof DeclaredType)) { + if (isClassOrRecord() && annotation == null && (annotationType.getAnnotation(Inherited.class) != null) && (getSuperclass() instanceof DeclaredType)) { TypeElement superDecl = (TypeElement) ((DeclaredType) getSuperclass()).asElement(); if ((superDecl != null) && (!Object.class.getName().equals(superDecl.getQualifiedName().toString()))) { return superDecl.getAnnotation(annotationType); @@ -164,6 +164,7 @@ public A getAnnotation(Class annotationType) { protected List loadProperties(PropertySpec spec) { HashMap getters = new HashMap(); HashMap setters = new HashMap(); + // TODO for (ExecutableElement method : getMethods()) { DecoratedExecutableElement decoratedMethod = (DecoratedExecutableElement) method; boolean getter = spec.isGetter(decoratedMethod); @@ -213,8 +214,8 @@ protected List loadEnumConstants() { return constants; } - public boolean isClass() { - return getKind() == ElementKind.CLASS; + public boolean isClassOrRecord() { + return getKind() == ElementKind.CLASS || getKind().name().equals("RECORD"); } public boolean isInterface() { diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/type/DecoratedTypeMirror.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/type/DecoratedTypeMirror.java index 71c6c1bb1..f5bfff915 100644 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/type/DecoratedTypeMirror.java +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/type/DecoratedTypeMirror.java @@ -143,7 +143,12 @@ public boolean isReferenceType() { return false; } public boolean isClass() { - return isDeclared() && ((DeclaredType)this.delegate).asElement().getKind() == ElementKind.CLASS; + return isDeclared() && isClassOrRecord(); + } + + private boolean isClassOrRecord() { + Element element = ((DeclaredType) this.delegate).asElement(); + return element.getKind() == ElementKind.CLASS || element.getKind().name().equals("RECORD"); } public boolean isDeclared() { diff --git a/javascript-client/src/main/java/com/webcohesion/enunciate/modules/javascript_client/ClientClassnameForMethod.java b/javascript-client/src/main/java/com/webcohesion/enunciate/modules/javascript_client/ClientClassnameForMethod.java index 5c77fc178..3eeeded0c 100644 --- a/javascript-client/src/main/java/com/webcohesion/enunciate/modules/javascript_client/ClientClassnameForMethod.java +++ b/javascript-client/src/main/java/com/webcohesion/enunciate/modules/javascript_client/ClientClassnameForMethod.java @@ -84,6 +84,7 @@ public ClientClassnameForMethod(Map conversions, EnunciateJackso classConversions.put(javax.xml.datatype.Duration.class.getName(), "String"); classConversions.put(jakarta.xml.bind.JAXBElement.class.getName(), "Object"); classConversions.put(Object.class.getName(), "Object"); + classConversions.put("java.lang.Record", "Object"); } @Override @@ -200,4 +201,4 @@ protected String getPackageSeparator() { return "."; } -} \ No newline at end of file +} diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java index f9ceb0b50..28d7cfe4a 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java @@ -191,7 +191,7 @@ protected Map loadKnownTypes() { knownTypes.put(java.net.URI.class.getName(), KnownXmlType.STRING); knownTypes.put(javax.xml.datatype.Duration.class.getName(), KnownXmlType.DURATION); knownTypes.put(java.lang.Object.class.getName(), KnownXmlType.ANY_TYPE); - knownTypes.put(java.lang.Record.class.getName(), KnownXmlType.ANY_TYPE); + knownTypes.put("java.lang.Record", KnownXmlType.ANY_TYPE); knownTypes.put(java.io.Serializable.class.getName(), KnownXmlType.ANY_TYPE); knownTypes.put(byte[].class.getName(), KnownXmlType.BASE64_BINARY); knownTypes.put(java.nio.ByteBuffer.class.getName(), KnownXmlType.BASE64_BINARY); @@ -473,7 +473,7 @@ protected void add(LocalElementDeclaration led, LinkedList stack) { protected void addReferencedTypeDefinitions(LocalElementDeclaration led, LinkedList stack) { addSeeAlsoTypeDefinitions(led, stack); DecoratedTypeElement scope = led.getElementScope(); - if (scope != null && scope.getKind() == ElementKind.CLASS && !isKnownTypeDefinition(scope)) { + if (scope != null && (scope.getKind() == ElementKind.CLASS || scope.getKind().name().equals("RECORD")) && !isKnownTypeDefinition(scope)) { add(createTypeDefinition(scope), stack); } TypeElement typeElement = null; @@ -485,7 +485,7 @@ protected void addReferencedTypeDefinitions(LocalElementDeclaration led, LinkedL } } - if (scope != null && scope.getKind() == ElementKind.CLASS && !isKnownTypeDefinition(typeElement)) { + if (scope != null && (scope.getKind() == ElementKind.CLASS || scope.getKind().name().equals("RECORD")) && !isKnownTypeDefinition(typeElement)) { add(createTypeDefinition(typeElement), stack); } } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/JaxbModule.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/JaxbModule.java index d0712eb0b..328b983ef 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/JaxbModule.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/JaxbModule.java @@ -160,7 +160,7 @@ else if (!this.jaxbContext.isKnownTypeDefinition((TypeElement) declaration) && i } protected boolean isExplicitTypeDefinition(Element declaration) { - if (declaration.getKind() != ElementKind.CLASS && declaration.getKind() != ElementKind.ENUM) { + if (declaration.getKind() != ElementKind.CLASS && declaration.getKind() != ElementKind.ENUM && !declaration.getKind().name().equals("RECORD")) { debug("%s isn't a potential JAXB type because it's not a class or an enum.", declaration); return false; } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java index 626456eae..897f914a9 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java @@ -35,18 +35,16 @@ import com.webcohesion.enunciate.modules.jaxb.model.types.XmlTypeFactory; import com.webcohesion.enunciate.modules.jaxb.model.util.JAXBUtil; import com.webcohesion.enunciate.modules.jaxb.model.util.MapType; +import com.webcohesion.enunciate.util.FieldOrRecordUtil; import com.webcohesion.enunciate.util.HasClientConvertibleType; import com.webcohesion.enunciate.util.OptionalUtils; import jakarta.activation.DataHandler; import javax.lang.model.element.Element; -import javax.lang.model.element.VariableElement; import javax.lang.model.type.*; -import javax.lang.model.util.ElementFilter; import jakarta.xml.bind.annotation.*; import javax.xml.namespace.QName; import java.util.*; -import java.util.concurrent.Callable; /** * An accessor for a field or method value into a type. @@ -380,7 +378,7 @@ private DecoratedElement getXmlIDAccessor(DecoratedDeclaredType classType) { return null; } - for (VariableElement field : ElementFilter.fieldsIn(declaration.getEnclosedElements())) { + for (Element field : FieldOrRecordUtil.extractFieldElements(declaration)) { if (field.getAnnotation(XmlID.class) != null) { return (DecoratedElement) field; } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/ComplexTypeDefinition.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/ComplexTypeDefinition.java index 1770dd94a..8e271da8d 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/ComplexTypeDefinition.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/ComplexTypeDefinition.java @@ -114,7 +114,7 @@ public boolean isBaseObject() { TypeElement superDeclaration = (TypeElement) this.env.getTypeUtils().asElement(superclass); return superDeclaration == null || Object.class.getName().equals(superDeclaration.getQualifiedName().toString()) - || Record.class.getName().equals(superDeclaration.getQualifiedName().toString()) + || "java.lang.Record".equals(superDeclaration.getQualifiedName().toString()) || isXmlTransient(superDeclaration); } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java index c91a42e7d..f6113d5bb 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java @@ -37,6 +37,8 @@ import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; + +import com.webcohesion.enunciate.util.FieldOrRecordUtil; import jakarta.xml.bind.annotation.*; import javax.xml.namespace.QName; import java.beans.Introspector; @@ -200,7 +202,7 @@ protected void aggregatePotentialAccessors(AccessorBag bag, DecoratedTypeElement aggregatePotentialAccessors(bag, superDeclaration, filter, true); } - for (VariableElement fieldDeclaration : ElementFilter.fieldsIn(clazz.getEnclosedElements())) { + for (javax.lang.model.element.Element fieldDeclaration : FieldOrRecordUtil.extractFieldElements(clazz)) { if (!filter.accept((DecoratedElement) fieldDeclaration)) { bag.fields.removeByName(fieldDeclaration); } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/types/XmlTypeVisitor.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/types/XmlTypeVisitor.java index af5ff28d4..7ac6c89bf 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/types/XmlTypeVisitor.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/types/XmlTypeVisitor.java @@ -23,9 +23,11 @@ import com.webcohesion.enunciate.modules.jaxb.model.util.MapType; import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.lang.model.type.*; import javax.lang.model.util.SimpleTypeVisitor6; +import java.util.Arrays; import java.util.LinkedList; /** @@ -73,21 +75,19 @@ public XmlType visitDeclared(DeclaredType declaredType, Context context) { return new MapXmlType(keyType, valueType); } else { - switch (declaredElement.getKind()) { - case ENUM: - case CLASS: - XmlType knownType = context.getContext().getKnownType(declaredElement); - if (knownType != null) { - return knownType; + String[] kinds = {ElementKind.CLASS.name(), ElementKind.ENUM.name(), "RECORD"}; + if(Arrays.binarySearch(kinds,declaredElement.getKind().name()) >=0) { + XmlType knownType = context.getContext().getKnownType(declaredElement); + if (knownType != null) { + return knownType; + } + else { + //type not known, not specified. Last chance: look for the type definition. + TypeDefinition typeDefinition = context.getContext().findTypeDefinition(declaredElement); + if (typeDefinition != null) { + return new XmlClassType(typeDefinition); } - else { - //type not known, not specified. Last chance: look for the type definition. - TypeDefinition typeDefinition = context.getContext().findTypeDefinition(declaredElement); - if (typeDefinition != null) { - return new XmlClassType(typeDefinition); - } - } - break; + } } } } diff --git a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java index e0d918e3f..269ad56f6 100644 --- a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java +++ b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java @@ -24,6 +24,7 @@ import com.webcohesion.enunciate.modules.jaxrs.model.util.JaxrsUtil; import com.webcohesion.enunciate.util.AnnotationUtils; +import com.webcohesion.enunciate.util.FieldOrRecordUtil; import jakarta.annotation.security.RolesAllowed; import javax.lang.model.element.*; import javax.lang.model.type.DeclaredType; @@ -119,7 +120,8 @@ protected List getSubresourceLocators(TypeElement delegate, } } - if (delegate.getKind() == ElementKind.CLASS) { + + if (delegate.getKind() == ElementKind.CLASS || delegate.getKind().name().equals("RECORD")) { TypeMirror superclass = delegate.getSuperclass(); if (superclass instanceof DeclaredType && ((DeclaredType)superclass).asElement() != null) { List superMethods = getSubresourceLocators((TypeElement) ((DeclaredType) superclass).asElement(), variableContext, context); @@ -179,7 +181,7 @@ protected List getResourceMethods(final TypeElement delegate, Ty } } - if (delegate.getKind() == ElementKind.CLASS) { + if (delegate.getKind() == ElementKind.CLASS || delegate.getKind().name().equals("RECORD")) { TypeMirror superclass = delegate.getSuperclass(); if (superclass instanceof DeclaredType && ((DeclaredType)superclass).asElement() != null) { DeclaredType declared = (DeclaredType) superclass; @@ -209,7 +211,7 @@ protected Set getResourceParameters(TypeElement delegate, Enu } Set resourceParameters = new TreeSet(); - for (VariableElement field : ElementFilter.fieldsIn(delegate.getEnclosedElements())) { + for (Element field : FieldOrRecordUtil.extractFieldElements(delegate)) { if (ResourceParameter.isResourceParameter(field, this.context)) { resourceParameters.add(new ResourceParameter(field, this)); } @@ -221,7 +223,7 @@ protected Set getResourceParameters(TypeElement delegate, Enu } } - if (delegate.getKind() == ElementKind.CLASS && delegate.getSuperclass() instanceof DeclaredType) { + if ((delegate.getKind() == ElementKind.CLASS || delegate.getKind().name().equals("RECORD")) && delegate.getSuperclass() instanceof DeclaredType) { Set superParams = getResourceParameters((TypeElement) ((DeclaredType) delegate.getSuperclass()).asElement(), context); for (ResourceParameter superParam : superParams) { if (!isHidden(superParam, resourceParameters)) { diff --git a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java index 870fc90fc..69ea9d560 100644 --- a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java +++ b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java @@ -25,6 +25,7 @@ import com.webcohesion.enunciate.metadata.rs.TypeHint; import com.webcohesion.enunciate.modules.jaxrs.EnunciateJaxrsContext; import com.webcohesion.enunciate.util.AnnotationUtils; +import com.webcohesion.enunciate.util.FieldOrRecordUtil; import com.webcohesion.enunciate.util.TypeHintUtils; import jakarta.annotation.Nullable; @@ -246,7 +247,7 @@ public static List getFormBeanParameters(VariableElement para private static void gatherFormBeanParameters(TypeMirror type, ArrayList beanParams, PathContext context) { if (type instanceof DeclaredType) { DecoratedTypeElement typeDeclaration = (DecoratedTypeElement) ElementDecorator.decorate(((DeclaredType) type).asElement(), context.getContext().getContext().getProcessingEnvironment()); - for (VariableElement field : ElementFilter.fieldsIn(typeDeclaration.getEnclosedElements())) { + for (Element field : FieldOrRecordUtil.extractFieldElements(typeDeclaration)) { if (isResourceParameter(field, context.getContext())) { beanParams.add(new ResourceParameter(field, context)); } @@ -265,7 +266,7 @@ else if (isBeanParameter(property)) { } } - if (typeDeclaration.getKind() == ElementKind.CLASS) { + if (typeDeclaration.getKind() == ElementKind.CLASS || typeDeclaration.getKind().name().equals("RECORD")) { gatherFormBeanParameters(typeDeclaration.getSuperclass(), beanParams, context); } } diff --git a/jaxws/src/main/java/com/webcohesion/enunciate/modules/jaxws/model/EndpointInterface.java b/jaxws/src/main/java/com/webcohesion/enunciate/modules/jaxws/model/EndpointInterface.java index 0e6cb2014..702098101 100644 --- a/jaxws/src/main/java/com/webcohesion/enunciate/modules/jaxws/model/EndpointInterface.java +++ b/jaxws/src/main/java/com/webcohesion/enunciate/modules/jaxws/model/EndpointInterface.java @@ -76,7 +76,7 @@ public EndpointInterface(TypeElement delegate, Set implementa annotation = getAnnotation(jakarta.jws.WebService.class); impls = new ArrayList(); if (annotation != null) { - if (isClass()) { + if (isClassOrRecord()) { //if the declaration is a class, the endpoint interface is implied... impls.add(new EndpointImplementation(getDelegate(), this, context)); } @@ -105,7 +105,7 @@ public EndpointInterface(TypeElement delegate, Set implementa } } - if (delegate.getKind() == ElementKind.CLASS) { + if (delegate.getKind() == ElementKind.CLASS || delegate.getKind().name().equals("RECORD")) { //the spec says we need to consider superclass methods, too... TypeMirror superclass = delegate.getSuperclass(); if (superclass instanceof DeclaredType) { @@ -310,7 +310,7 @@ public Collection getEndpointImplementations() { * A quick check to see if a declaration is an endpoint implementation. */ protected boolean isEndpointImplementation(TypeElement declaration) { - if (declaration.getKind() == ElementKind.CLASS && !declaration.getQualifiedName().equals(getQualifiedName())) { + if ((declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) && !declaration.getQualifiedName().equals(getQualifiedName())) { WebService webServiceInfo = declaration.getAnnotation(WebService.class); return webServiceInfo != null && getQualifiedName().toString().equals(webServiceInfo.endpointInterface()); } diff --git a/obj-c-xml-client/src/main/java/com/webcohesion/enunciate/modules/objc_client/ClientClassnameForMethod.java b/obj-c-xml-client/src/main/java/com/webcohesion/enunciate/modules/objc_client/ClientClassnameForMethod.java index 2a3d68292..9f849ffe1 100644 --- a/obj-c-xml-client/src/main/java/com/webcohesion/enunciate/modules/objc_client/ClientClassnameForMethod.java +++ b/obj-c-xml-client/src/main/java/com/webcohesion/enunciate/modules/objc_client/ClientClassnameForMethod.java @@ -95,7 +95,7 @@ else if (isCollection(declaration)) { if (adapterType != null) { return convert(adapterType.getAdaptingType()); } - if (declaration.getKind() == ElementKind.CLASS) { + if (declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement @@ -191,4 +191,4 @@ public String convert(TypeVariable typeVariable) throws TemplateModelException { return conversion; } -} \ No newline at end of file +} diff --git a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java index 96875d8a9..12c679397 100644 --- a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java +++ b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java @@ -24,6 +24,7 @@ import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.javac.decorations.type.TypeVariableContext; import com.webcohesion.enunciate.util.AnnotationUtils; +import com.webcohesion.enunciate.util.FieldOrRecordUtil; import org.springframework.web.bind.annotation.*; import javax.lang.model.element.*; @@ -183,7 +184,7 @@ private static void gatherFormObjectParameters(TypeMirror type, ArrayList methods = context.getHttpMethods(); ResourceParameterType defaultType = methods.contains("POST") ? ResourceParameterType.FORM : ResourceParameterType.QUERY; DecoratedTypeElement typeDeclaration = (DecoratedTypeElement) ElementDecorator.decorate(((DeclaredType) type).asElement(), context.getContext().getContext().getProcessingEnvironment()); - for (VariableElement field : ElementFilter.fieldsIn(typeDeclaration.getEnclosedElements())) { + for (Element field : FieldOrRecordUtil.extractFieldElements(typeDeclaration)) { DecoratedVariableElement decorated = (DecoratedVariableElement) field; if (!decorated.isFinal() && !decorated.isTransient() && decorated.isPublic()) { params.add(new SimpleRequestParameter(decorated, context, defaultType)); @@ -196,7 +197,7 @@ private static void gatherFormObjectParameters(TypeMirror type, ArrayList getRequestMappings(final TypeElement delegate, Ty } } - if (delegate.getKind() == ElementKind.CLASS) { + if (delegate.getKind() == ElementKind.CLASS || delegate.getKind().name().equals("RECORD")) { TypeMirror superclass = delegate.getSuperclass(); if (superclass instanceof DeclaredType && ((DeclaredType) superclass).asElement() != null) { DeclaredType declared = (DeclaredType) superclass; diff --git a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/SpringControllerAdvice.java b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/SpringControllerAdvice.java index 50a669edb..6b2f2b2de 100644 --- a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/SpringControllerAdvice.java +++ b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/SpringControllerAdvice.java @@ -187,7 +187,7 @@ protected List findRequestMappingAdvice(RequestMapping req } } - if (controllerAdvice.getKind() == ElementKind.CLASS) { + if (controllerAdvice.getKind() == ElementKind.CLASS || controllerAdvice.getKind().name().equals("RECORD")) { TypeMirror superclass = controllerAdvice.getSuperclass(); if (superclass instanceof DeclaredType && ((DeclaredType)superclass).asElement() != null) { DeclaredType declared = (DeclaredType) superclass; From 2507e127c2a46a30c26d622ae93b5c65767e4cda Mon Sep 17 00:00:00 2001 From: Joakim Holm Date: Thu, 12 Oct 2023 16:08:17 +0200 Subject: [PATCH 04/11] Make record fields show up as properties on types --- .../enunciate/util/FieldOrRecordUtil.java | 14 +++++++------- .../modules/jackson/model/AccessorFilter.java | 4 ++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java b/core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java index 20d389237..3134314ba 100644 --- a/core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java +++ b/core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java @@ -1,11 +1,8 @@ package com.webcohesion.enunciate.util; -import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; - import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.lang.model.util.ElementFilter; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; @@ -14,13 +11,16 @@ */ public final class FieldOrRecordUtil { - @SuppressWarnings({"unchecked"}) public static List extractFieldElements(TypeElement clazz) { if (isRecord(clazz)) { try { - Method method = clazz.getClass().getMethod("getRecordComponents"); - List elements = (List) method.invoke(clazz); - return new ArrayList<>(elements); + List elements = new ArrayList<>(); + for(Element element : clazz.getEnclosedElements()) { + if(element.getKind().name().equals("RECORD_COMPONENT")) { + elements.add(element); + } + } + return elements; } catch (Exception e) { throw new RuntimeException(e); } diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/AccessorFilter.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/AccessorFilter.java index ac1419aeb..f3b61107b 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/AccessorFilter.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/AccessorFilter.java @@ -128,6 +128,10 @@ else if (element instanceof DecoratedVariableElement) { return true; } + if(element.getKind().name().equals("RECORD_COMPONENT")) { + return true; + } + return false; } From 04aa9079b48ebc8ebbde0b26f260100d8b82bebd Mon Sep 17 00:00:00 2001 From: Jesenko Mehmedbasic Date: Tue, 17 Oct 2023 11:26:46 +0200 Subject: [PATCH 05/11] Get @param docs for java.util.Record objects --- .../javac/decorations/DecoratedElements.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/DecoratedElements.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/DecoratedElements.java index e44982a13..68fe2a60f 100644 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/DecoratedElements.java +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/DecoratedElements.java @@ -22,6 +22,7 @@ import com.webcohesion.enunciate.javac.decorations.element.DecoratedElement; import com.webcohesion.enunciate.javac.decorations.element.DecoratedExecutableElement; import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; +import com.webcohesion.enunciate.javac.javadoc.JavaDoc; import javax.lang.model.element.*; import javax.lang.model.util.Elements; @@ -70,14 +71,31 @@ public String getDocComment(Element e) { e = ((DecoratedElement) e).getDelegate(); } + String recordComponentName = null; + if (e.getKind().toString().equals("RECORD_COMPONENT")) { + recordComponentName = e.getSimpleName().toString(); + e = e.getEnclosingElement(); + } + String docComment; if (e instanceof ElementAdaptor) { docComment = ((ElementAdaptor) e).getDocComment(); - } - else { + } else { docComment = delegate.getDocComment(e); } + if (recordComponentName != null) { + JavaDoc localDoc = new JavaDoc(docComment, null, null, this.env); + JavaDoc.JavaDocTagList paramDocs = localDoc.get("param"); + if (paramDocs != null) { + for (String paramDoc : paramDocs) { + if (paramDoc.startsWith(recordComponentName + " ")) { + docComment = paramDoc.substring(recordComponentName.length()).trim(); + } + } + } + } + return docComment; } From fa947529c8e83e2819d3df47136c9e9565e0a99e Mon Sep 17 00:00:00 2001 From: Jesenko Mehmedbasic Date: Tue, 17 Oct 2023 11:28:27 +0200 Subject: [PATCH 06/11] Rename FieldOrRecordUtil#extractFieldElements to fieldsOrRecordComponentsIn --- .../com/webcohesion/enunciate/util/FieldOrRecordUtil.java | 2 +- .../enunciate/modules/jackson/model/TypeDefinition.java | 5 ++--- .../webcohesion/enunciate/modules/jaxb/model/Accessor.java | 2 +- .../enunciate/modules/jaxb/model/TypeDefinition.java | 4 +--- .../webcohesion/enunciate/modules/jaxrs/model/Resource.java | 2 +- .../enunciate/modules/jaxrs/model/ResourceParameter.java | 3 +-- .../modules/spring_web/model/RequestParameterFactory.java | 3 +-- 7 files changed, 8 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java b/core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java index 3134314ba..466fa7431 100644 --- a/core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java +++ b/core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java @@ -11,7 +11,7 @@ */ public final class FieldOrRecordUtil { - public static List extractFieldElements(TypeElement clazz) { + public static List fieldsOrRecordComponentsIn(TypeElement clazz) { if (isRecord(clazz)) { try { List elements = new ArrayList<>(); diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java index 3326fee59..7c439c7f4 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java @@ -43,7 +43,6 @@ import jakarta.xml.bind.annotation.XmlType; import java.lang.annotation.Annotation; -import java.lang.reflect.Method; import java.util.*; import java.util.function.Function; @@ -221,10 +220,10 @@ protected void aggregatePotentialAccessors(AccessorBag bag, DecoratedTypeElement } } - List fieldElements = new ArrayList<>(FieldOrRecordUtil.extractFieldElements(clazz)); + List fieldElements = new ArrayList<>(FieldOrRecordUtil.fieldsOrRecordComponentsIn(clazz)); if (mixin != null) { //replace all mixin fields. - for (Element mixinField : FieldOrRecordUtil.extractFieldElements(mixin)) { + for (Element mixinField : FieldOrRecordUtil.fieldsOrRecordComponentsIn(mixin)) { int index = indexOf(fieldElements, mixinField.getSimpleName().toString()); if (index >= 0) { fieldElements.set(index, mixinField); diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java index 897f914a9..0134c96cd 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java @@ -378,7 +378,7 @@ private DecoratedElement getXmlIDAccessor(DecoratedDeclaredType classType) { return null; } - for (Element field : FieldOrRecordUtil.extractFieldElements(declaration)) { + for (Element field : FieldOrRecordUtil.fieldsOrRecordComponentsIn(declaration)) { if (field.getAnnotation(XmlID.class) != null) { return (DecoratedElement) field; } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java index f6113d5bb..e221fe717 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java @@ -32,7 +32,6 @@ import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; import javax.lang.model.type.MirroredTypesException; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; @@ -43,7 +42,6 @@ import javax.xml.namespace.QName; import java.beans.Introspector; import java.util.*; -import java.util.concurrent.Callable; /** * A xml type definition. @@ -202,7 +200,7 @@ protected void aggregatePotentialAccessors(AccessorBag bag, DecoratedTypeElement aggregatePotentialAccessors(bag, superDeclaration, filter, true); } - for (javax.lang.model.element.Element fieldDeclaration : FieldOrRecordUtil.extractFieldElements(clazz)) { + for (javax.lang.model.element.Element fieldDeclaration : FieldOrRecordUtil.fieldsOrRecordComponentsIn(clazz)) { if (!filter.accept((DecoratedElement) fieldDeclaration)) { bag.fields.removeByName(fieldDeclaration); } diff --git a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java index 269ad56f6..48904a1a2 100644 --- a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java +++ b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java @@ -211,7 +211,7 @@ protected Set getResourceParameters(TypeElement delegate, Enu } Set resourceParameters = new TreeSet(); - for (Element field : FieldOrRecordUtil.extractFieldElements(delegate)) { + for (Element field : FieldOrRecordUtil.fieldsOrRecordComponentsIn(delegate)) { if (ResourceParameter.isResourceParameter(field, this.context)) { resourceParameters.add(new ResourceParameter(field, this)); } diff --git a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java index 69ea9d560..01156f4fc 100644 --- a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java +++ b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java @@ -32,7 +32,6 @@ import javax.lang.model.element.*; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.ElementFilter; import java.util.*; @@ -247,7 +246,7 @@ public static List getFormBeanParameters(VariableElement para private static void gatherFormBeanParameters(TypeMirror type, ArrayList beanParams, PathContext context) { if (type instanceof DeclaredType) { DecoratedTypeElement typeDeclaration = (DecoratedTypeElement) ElementDecorator.decorate(((DeclaredType) type).asElement(), context.getContext().getContext().getProcessingEnvironment()); - for (Element field : FieldOrRecordUtil.extractFieldElements(typeDeclaration)) { + for (Element field : FieldOrRecordUtil.fieldsOrRecordComponentsIn(typeDeclaration)) { if (isResourceParameter(field, context.getContext())) { beanParams.add(new ResourceParameter(field, context)); } diff --git a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java index 12c679397..5c20d7696 100644 --- a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java +++ b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java @@ -32,7 +32,6 @@ import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeVariable; -import javax.lang.model.util.ElementFilter; import java.util.*; /** @@ -184,7 +183,7 @@ private static void gatherFormObjectParameters(TypeMirror type, ArrayList methods = context.getHttpMethods(); ResourceParameterType defaultType = methods.contains("POST") ? ResourceParameterType.FORM : ResourceParameterType.QUERY; DecoratedTypeElement typeDeclaration = (DecoratedTypeElement) ElementDecorator.decorate(((DeclaredType) type).asElement(), context.getContext().getContext().getProcessingEnvironment()); - for (Element field : FieldOrRecordUtil.extractFieldElements(typeDeclaration)) { + for (Element field : FieldOrRecordUtil.fieldsOrRecordComponentsIn(typeDeclaration)) { DecoratedVariableElement decorated = (DecoratedVariableElement) field; if (!decorated.isFinal() && !decorated.isTransient() && decorated.isPublic()) { params.add(new SimpleRequestParameter(decorated, context, defaultType)); From b97da674e7c0e41f213c5c341252cb06626cb53c Mon Sep 17 00:00:00 2001 From: Jesenko Mehmedbasic Date: Tue, 17 Oct 2023 11:31:22 +0200 Subject: [PATCH 07/11] Rename FieldOrRecordUtil to CompatElementFilter. --- .../{FieldOrRecordUtil.java => CompatElementFilter.java} | 6 ++++-- .../enunciate/modules/jackson/model/TypeDefinition.java | 6 +++--- .../webcohesion/enunciate/modules/jaxb/model/Accessor.java | 4 ++-- .../enunciate/modules/jaxb/model/TypeDefinition.java | 4 ++-- .../webcohesion/enunciate/modules/jaxrs/model/Resource.java | 4 ++-- .../enunciate/modules/jaxrs/model/ResourceParameter.java | 4 ++-- .../modules/spring_web/model/RequestParameterFactory.java | 4 ++-- 7 files changed, 17 insertions(+), 15 deletions(-) rename core/src/main/java/com/webcohesion/enunciate/util/{FieldOrRecordUtil.java => CompatElementFilter.java} (87%) diff --git a/core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java b/core/src/main/java/com/webcohesion/enunciate/util/CompatElementFilter.java similarity index 87% rename from core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java rename to core/src/main/java/com/webcohesion/enunciate/util/CompatElementFilter.java index 466fa7431..edd75bb0a 100644 --- a/core/src/main/java/com/webcohesion/enunciate/util/FieldOrRecordUtil.java +++ b/core/src/main/java/com/webcohesion/enunciate/util/CompatElementFilter.java @@ -7,9 +7,11 @@ import java.util.List; /** - * FieldOrRecordUtil. + * Unified utility for handling java.lang.Record on JDK < 16. */ -public final class FieldOrRecordUtil { +public final class CompatElementFilter { + private CompatElementFilter() { + } public static List fieldsOrRecordComponentsIn(TypeElement clazz) { if (isRecord(clazz)) { diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java index 7c439c7f4..8aa8cfe17 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java @@ -32,7 +32,7 @@ import com.webcohesion.enunciate.modules.jackson.javac.ToStringValueProperty; import com.webcohesion.enunciate.util.AccessorBag; import com.webcohesion.enunciate.util.AnnotationUtils; -import com.webcohesion.enunciate.util.FieldOrRecordUtil; +import com.webcohesion.enunciate.util.CompatElementFilter; import com.webcohesion.enunciate.util.SortedList; import javax.lang.model.element.*; @@ -220,10 +220,10 @@ protected void aggregatePotentialAccessors(AccessorBag bag, DecoratedTypeElement } } - List fieldElements = new ArrayList<>(FieldOrRecordUtil.fieldsOrRecordComponentsIn(clazz)); + List fieldElements = new ArrayList<>(CompatElementFilter.fieldsOrRecordComponentsIn(clazz)); if (mixin != null) { //replace all mixin fields. - for (Element mixinField : FieldOrRecordUtil.fieldsOrRecordComponentsIn(mixin)) { + for (Element mixinField : CompatElementFilter.fieldsOrRecordComponentsIn(mixin)) { int index = indexOf(fieldElements, mixinField.getSimpleName().toString()); if (index >= 0) { fieldElements.set(index, mixinField); diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java index 0134c96cd..5b30fca0a 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java @@ -35,7 +35,7 @@ import com.webcohesion.enunciate.modules.jaxb.model.types.XmlTypeFactory; import com.webcohesion.enunciate.modules.jaxb.model.util.JAXBUtil; import com.webcohesion.enunciate.modules.jaxb.model.util.MapType; -import com.webcohesion.enunciate.util.FieldOrRecordUtil; +import com.webcohesion.enunciate.util.CompatElementFilter; import com.webcohesion.enunciate.util.HasClientConvertibleType; import com.webcohesion.enunciate.util.OptionalUtils; @@ -378,7 +378,7 @@ private DecoratedElement getXmlIDAccessor(DecoratedDeclaredType classType) { return null; } - for (Element field : FieldOrRecordUtil.fieldsOrRecordComponentsIn(declaration)) { + for (Element field : CompatElementFilter.fieldsOrRecordComponentsIn(declaration)) { if (field.getAnnotation(XmlID.class) != null) { return (DecoratedElement) field; } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java index e221fe717..76151e49c 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java @@ -37,7 +37,7 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; -import com.webcohesion.enunciate.util.FieldOrRecordUtil; +import com.webcohesion.enunciate.util.CompatElementFilter; import jakarta.xml.bind.annotation.*; import javax.xml.namespace.QName; import java.beans.Introspector; @@ -200,7 +200,7 @@ protected void aggregatePotentialAccessors(AccessorBag bag, DecoratedTypeElement aggregatePotentialAccessors(bag, superDeclaration, filter, true); } - for (javax.lang.model.element.Element fieldDeclaration : FieldOrRecordUtil.fieldsOrRecordComponentsIn(clazz)) { + for (javax.lang.model.element.Element fieldDeclaration : CompatElementFilter.fieldsOrRecordComponentsIn(clazz)) { if (!filter.accept((DecoratedElement) fieldDeclaration)) { bag.fields.removeByName(fieldDeclaration); } diff --git a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java index 48904a1a2..f94e7b94f 100644 --- a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java +++ b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java @@ -24,7 +24,7 @@ import com.webcohesion.enunciate.modules.jaxrs.model.util.JaxrsUtil; import com.webcohesion.enunciate.util.AnnotationUtils; -import com.webcohesion.enunciate.util.FieldOrRecordUtil; +import com.webcohesion.enunciate.util.CompatElementFilter; import jakarta.annotation.security.RolesAllowed; import javax.lang.model.element.*; import javax.lang.model.type.DeclaredType; @@ -211,7 +211,7 @@ protected Set getResourceParameters(TypeElement delegate, Enu } Set resourceParameters = new TreeSet(); - for (Element field : FieldOrRecordUtil.fieldsOrRecordComponentsIn(delegate)) { + for (Element field : CompatElementFilter.fieldsOrRecordComponentsIn(delegate)) { if (ResourceParameter.isResourceParameter(field, this.context)) { resourceParameters.add(new ResourceParameter(field, this)); } diff --git a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java index 01156f4fc..eda07d950 100644 --- a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java +++ b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java @@ -25,7 +25,7 @@ import com.webcohesion.enunciate.metadata.rs.TypeHint; import com.webcohesion.enunciate.modules.jaxrs.EnunciateJaxrsContext; import com.webcohesion.enunciate.util.AnnotationUtils; -import com.webcohesion.enunciate.util.FieldOrRecordUtil; +import com.webcohesion.enunciate.util.CompatElementFilter; import com.webcohesion.enunciate.util.TypeHintUtils; import jakarta.annotation.Nullable; @@ -246,7 +246,7 @@ public static List getFormBeanParameters(VariableElement para private static void gatherFormBeanParameters(TypeMirror type, ArrayList beanParams, PathContext context) { if (type instanceof DeclaredType) { DecoratedTypeElement typeDeclaration = (DecoratedTypeElement) ElementDecorator.decorate(((DeclaredType) type).asElement(), context.getContext().getContext().getProcessingEnvironment()); - for (Element field : FieldOrRecordUtil.fieldsOrRecordComponentsIn(typeDeclaration)) { + for (Element field : CompatElementFilter.fieldsOrRecordComponentsIn(typeDeclaration)) { if (isResourceParameter(field, context.getContext())) { beanParams.add(new ResourceParameter(field, context)); } diff --git a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java index 5c20d7696..0dbb8daca 100644 --- a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java +++ b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java @@ -24,7 +24,7 @@ import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.javac.decorations.type.TypeVariableContext; import com.webcohesion.enunciate.util.AnnotationUtils; -import com.webcohesion.enunciate.util.FieldOrRecordUtil; +import com.webcohesion.enunciate.util.CompatElementFilter; import org.springframework.web.bind.annotation.*; import javax.lang.model.element.*; @@ -183,7 +183,7 @@ private static void gatherFormObjectParameters(TypeMirror type, ArrayList methods = context.getHttpMethods(); ResourceParameterType defaultType = methods.contains("POST") ? ResourceParameterType.FORM : ResourceParameterType.QUERY; DecoratedTypeElement typeDeclaration = (DecoratedTypeElement) ElementDecorator.decorate(((DeclaredType) type).asElement(), context.getContext().getContext().getProcessingEnvironment()); - for (Element field : FieldOrRecordUtil.fieldsOrRecordComponentsIn(typeDeclaration)) { + for (Element field : CompatElementFilter.fieldsOrRecordComponentsIn(typeDeclaration)) { DecoratedVariableElement decorated = (DecoratedVariableElement) field; if (!decorated.isFinal() && !decorated.isTransient() && decorated.isPublic()) { params.add(new SimpleRequestParameter(decorated, context, defaultType)); From eef44d4567e230cad57b38cbf916ba4638b66ea5 Mon Sep 17 00:00:00 2001 From: Jesenko Mehmedbasic Date: Tue, 17 Oct 2023 11:50:49 +0200 Subject: [PATCH 08/11] Restructure the record compatibility code and make it prettier --- .../enunciate/util/CompatElementFilter.java | 43 ------------------- .../modules/jackson/model/AccessorFilter.java | 4 +- .../modules/jackson/model/TypeDefinition.java | 4 +- .../enunciate/javac/CompatElementFilter.java | 36 ++++++++++++++++ .../enunciate/javac/RecordCompatibility.java | 38 ++++++++++++++++ .../javac/decorations/DecoratedElements.java | 20 ++++----- .../javac/javadoc/ParamDocComment.java | 2 +- .../modules/jaxb/model/Accessor.java | 2 +- .../modules/jaxb/model/TypeDefinition.java | 2 +- .../modules/jaxrs/model/Resource.java | 2 +- .../jaxrs/model/ResourceParameter.java | 2 +- .../jaxrs/model/util/RSParamDocComment.java | 2 +- .../model/RequestParameterFactory.java | 2 +- 13 files changed, 95 insertions(+), 64 deletions(-) delete mode 100644 core/src/main/java/com/webcohesion/enunciate/util/CompatElementFilter.java create mode 100644 javac-support/src/main/java/com/webcohesion/enunciate/javac/CompatElementFilter.java create mode 100644 javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java diff --git a/core/src/main/java/com/webcohesion/enunciate/util/CompatElementFilter.java b/core/src/main/java/com/webcohesion/enunciate/util/CompatElementFilter.java deleted file mode 100644 index edd75bb0a..000000000 --- a/core/src/main/java/com/webcohesion/enunciate/util/CompatElementFilter.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.webcohesion.enunciate.util; - -import javax.lang.model.element.Element; -import javax.lang.model.element.TypeElement; -import javax.lang.model.util.ElementFilter; -import java.util.ArrayList; -import java.util.List; - -/** - * Unified utility for handling java.lang.Record on JDK < 16. - */ -public final class CompatElementFilter { - private CompatElementFilter() { - } - - public static List fieldsOrRecordComponentsIn(TypeElement clazz) { - if (isRecord(clazz)) { - try { - List elements = new ArrayList<>(); - for(Element element : clazz.getEnclosedElements()) { - if(element.getKind().name().equals("RECORD_COMPONENT")) { - elements.add(element); - } - } - return elements; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - else { - return new ArrayList<>(ElementFilter.fieldsIn(clazz.getEnclosedElements())); - } - } - - - private static boolean isRecord(TypeElement clazz) { - if (clazz.getSuperclass() == null) { - return false; - } - - return clazz.getSuperclass().toString().equals("java.lang.Record"); - } -} diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/AccessorFilter.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/AccessorFilter.java index f3b61107b..f07f86d01 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/AccessorFilter.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/AccessorFilter.java @@ -25,6 +25,8 @@ import com.webcohesion.enunciate.modules.jackson.EnunciateJacksonContext; import javax.lang.model.element.Modifier; + +import com.webcohesion.enunciate.javac.RecordCompatibility; import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlTransient; import java.util.Collections; @@ -128,7 +130,7 @@ else if (element instanceof DecoratedVariableElement) { return true; } - if(element.getKind().name().equals("RECORD_COMPONENT")) { + if(RecordCompatibility.isRecordComponent(element)) { return true; } diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java index 8aa8cfe17..ab6178d72 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java @@ -32,7 +32,7 @@ import com.webcohesion.enunciate.modules.jackson.javac.ToStringValueProperty; import com.webcohesion.enunciate.util.AccessorBag; import com.webcohesion.enunciate.util.AnnotationUtils; -import com.webcohesion.enunciate.util.CompatElementFilter; +import com.webcohesion.enunciate.javac.CompatElementFilter; import com.webcohesion.enunciate.util.SortedList; import javax.lang.model.element.*; @@ -220,7 +220,7 @@ protected void aggregatePotentialAccessors(AccessorBag bag, DecoratedTypeElement } } - List fieldElements = new ArrayList<>(CompatElementFilter.fieldsOrRecordComponentsIn(clazz)); + List fieldElements = CompatElementFilter.fieldsOrRecordComponentsIn(clazz); if (mixin != null) { //replace all mixin fields. for (Element mixinField : CompatElementFilter.fieldsOrRecordComponentsIn(mixin)) { diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/CompatElementFilter.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/CompatElementFilter.java new file mode 100644 index 000000000..3da4f6a01 --- /dev/null +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/CompatElementFilter.java @@ -0,0 +1,36 @@ +package com.webcohesion.enunciate.javac; + +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.ElementFilter; +import java.util.ArrayList; +import java.util.List; + +/** + * Unified utility for handling java.lang.Record on JDK < 16. + */ +public final class CompatElementFilter { + private CompatElementFilter() { + } + + /** + * Get all fields in the class. If it is a java.lang.Record then get all the record components. + * + * @param clazz the class to + * @return a list of elements + */ + public static List fieldsOrRecordComponentsIn(TypeElement clazz) { + if (RecordCompatibility.isRecord(clazz)) { + List elements = new ArrayList<>(); + for (Element element : clazz.getEnclosedElements()) { + if (RecordCompatibility.isRecordComponent(element)) { + elements.add(element); + } + } + return elements; + } + else { + return new ArrayList<>(ElementFilter.fieldsIn(clazz.getEnclosedElements())); + } + } +} diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java new file mode 100644 index 000000000..2eed1fa2f --- /dev/null +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java @@ -0,0 +1,38 @@ +package com.webcohesion.enunciate.javac; + +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import java.security.PublicKey; + +/** + * Aids in adding record compatibility for JDK < 16. + */ + +public final class RecordCompatibility { + private RecordCompatibility() { + } + + /** + * Check if the element is a record component. + * + * @param element the element to test + * @return true if it's a record component + */ + public static boolean isRecordComponent(Element element) { + return element != null && element.getKind().name().equals("RECORD_COMPONENT"); + } + + /** + * Check if the element is a record. + * + * @param element the element to test + * @return true if it's a record + */ + public static boolean isRecord(TypeElement element) { + if (element.getSuperclass() == null) { + return false; + } + + return element.getSuperclass().toString().equals("java.lang.Record"); + } +} diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/DecoratedElements.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/DecoratedElements.java index 68fe2a60f..dfd68e531 100644 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/DecoratedElements.java +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/DecoratedElements.java @@ -15,6 +15,7 @@ */ package com.webcohesion.enunciate.javac.decorations; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.adaptors.ElementAdaptor; import com.webcohesion.enunciate.javac.decorations.adaptors.ExecutableElementAdaptor; import com.webcohesion.enunciate.javac.decorations.adaptors.TypeElementAdaptor; @@ -23,10 +24,12 @@ import com.webcohesion.enunciate.javac.decorations.element.DecoratedExecutableElement; import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; import com.webcohesion.enunciate.javac.javadoc.JavaDoc; +import com.webcohesion.enunciate.javac.javadoc.ParamDocComment; import javax.lang.model.element.*; import javax.lang.model.util.Elements; import java.io.Writer; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -72,7 +75,7 @@ public String getDocComment(Element e) { } String recordComponentName = null; - if (e.getKind().toString().equals("RECORD_COMPONENT")) { + if (RecordCompatibility.isRecordComponent(e)) { recordComponentName = e.getSimpleName().toString(); e = e.getEnclosingElement(); } @@ -80,20 +83,15 @@ public String getDocComment(Element e) { String docComment; if (e instanceof ElementAdaptor) { docComment = ((ElementAdaptor) e).getDocComment(); - } else { + } + else { docComment = delegate.getDocComment(e); } if (recordComponentName != null) { - JavaDoc localDoc = new JavaDoc(docComment, null, null, this.env); - JavaDoc.JavaDocTagList paramDocs = localDoc.get("param"); - if (paramDocs != null) { - for (String paramDoc : paramDocs) { - if (paramDoc.startsWith(recordComponentName + " ")) { - docComment = paramDoc.substring(recordComponentName.length()).trim(); - } - } - } + JavaDoc recordDoc = new JavaDoc(docComment, null, null, this.env); + HashMap params = ParamDocComment.loadParamsComments("param", recordDoc); + docComment = params.get(recordComponentName); } return docComment; diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/javadoc/ParamDocComment.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/javadoc/ParamDocComment.java index 16a873452..79981a366 100644 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/javadoc/ParamDocComment.java +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/javadoc/ParamDocComment.java @@ -42,7 +42,7 @@ protected HashMap loadParamsComments(JavaDoc javaDoc) { return loadParamsComments("param", javaDoc); } - protected HashMap loadParamsComments(String tagName, JavaDoc jd) { + public static HashMap loadParamsComments(String tagName, JavaDoc jd) { HashMap paramComments = new HashMap(); if (jd.get(tagName) != null) { for (String paramDoc : jd.get(tagName)) { diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java index 5b30fca0a..e01652207 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java @@ -35,7 +35,7 @@ import com.webcohesion.enunciate.modules.jaxb.model.types.XmlTypeFactory; import com.webcohesion.enunciate.modules.jaxb.model.util.JAXBUtil; import com.webcohesion.enunciate.modules.jaxb.model.util.MapType; -import com.webcohesion.enunciate.util.CompatElementFilter; +import com.webcohesion.enunciate.javac.CompatElementFilter; import com.webcohesion.enunciate.util.HasClientConvertibleType; import com.webcohesion.enunciate.util.OptionalUtils; diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java index 76151e49c..ee25d8605 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java @@ -37,7 +37,7 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; -import com.webcohesion.enunciate.util.CompatElementFilter; +import com.webcohesion.enunciate.javac.CompatElementFilter; import jakarta.xml.bind.annotation.*; import javax.xml.namespace.QName; import java.beans.Introspector; diff --git a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java index f94e7b94f..ab98fed95 100644 --- a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java +++ b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java @@ -24,7 +24,7 @@ import com.webcohesion.enunciate.modules.jaxrs.model.util.JaxrsUtil; import com.webcohesion.enunciate.util.AnnotationUtils; -import com.webcohesion.enunciate.util.CompatElementFilter; +import com.webcohesion.enunciate.javac.CompatElementFilter; import jakarta.annotation.security.RolesAllowed; import javax.lang.model.element.*; import javax.lang.model.type.DeclaredType; diff --git a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java index eda07d950..aa1369b46 100644 --- a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java +++ b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java @@ -25,7 +25,7 @@ import com.webcohesion.enunciate.metadata.rs.TypeHint; import com.webcohesion.enunciate.modules.jaxrs.EnunciateJaxrsContext; import com.webcohesion.enunciate.util.AnnotationUtils; -import com.webcohesion.enunciate.util.CompatElementFilter; +import com.webcohesion.enunciate.javac.CompatElementFilter; import com.webcohesion.enunciate.util.TypeHintUtils; import jakarta.annotation.Nullable; diff --git a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/util/RSParamDocComment.java b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/util/RSParamDocComment.java index 438f24ea9..e2f578150 100644 --- a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/util/RSParamDocComment.java +++ b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/util/RSParamDocComment.java @@ -17,7 +17,7 @@ public RSParamDocComment(DecoratedExecutableElement executableElement, String pa @Override protected HashMap loadParamsComments(JavaDoc javaDoc) { - HashMap paramComments = super.loadParamsComments("RSParam", javaDoc); + HashMap paramComments = ParamDocComment.loadParamsComments("RSParam", javaDoc); paramComments.putAll(super.loadParamsComments(javaDoc)); return paramComments; } diff --git a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java index 0dbb8daca..0dc0255b6 100644 --- a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java +++ b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java @@ -24,7 +24,7 @@ import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.javac.decorations.type.TypeVariableContext; import com.webcohesion.enunciate.util.AnnotationUtils; -import com.webcohesion.enunciate.util.CompatElementFilter; +import com.webcohesion.enunciate.javac.CompatElementFilter; import org.springframework.web.bind.annotation.*; import javax.lang.model.element.*; From 16d2cb6c25122299ee2c3442122db95806d31535 Mon Sep 17 00:00:00 2001 From: Jesenko Mehmedbasic Date: Tue, 17 Oct 2023 13:04:58 +0200 Subject: [PATCH 09/11] Use RecordCompatibility class to check for whether type declarations are records --- .../c_client/ClientClassnameForMethod.java | 3 ++- .../ClientClassnameForMethod.java | 3 ++- .../ClientClassnameForMethod.java | 3 ++- .../modules/jackson/JacksonModule.java | 3 ++- .../modules/jackson/model/TypeDefinition.java | 3 ++- .../jackson/model/types/JsonTypeVisitor.java | 3 ++- .../ClientClassnameForMethod.java | 3 ++- .../ClientClassnameForMethod.java | 3 ++- .../enunciate/javac/RecordCompatibility.java | 25 ++++++++++++------- .../element/DecoratedTypeElement.java | 7 ++---- .../decorations/type/DecoratedTypeMirror.java | 3 ++- .../modules/jaxb/EnunciateJaxbContext.java | 5 ++-- .../enunciate/modules/jaxb/JaxbModule.java | 3 ++- .../jaxb/model/types/XmlTypeVisitor.java | 3 ++- .../modules/jaxrs/model/Resource.java | 7 +++--- .../jaxrs/model/ResourceParameter.java | 3 ++- .../jaxws/model/EndpointInterface.java | 7 +++--- .../objc_client/ClientClassnameForMethod.java | 3 ++- .../model/RequestParameterFactory.java | 3 ++- .../spring_web/model/SpringController.java | 3 ++- .../model/SpringControllerAdvice.java | 3 ++- 21 files changed, 61 insertions(+), 38 deletions(-) diff --git a/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java b/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java index 24fdfcb89..22ce6c3ed 100644 --- a/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java +++ b/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java @@ -15,6 +15,7 @@ */ package com.webcohesion.enunciate.modules.c_client; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.ClientName; @@ -96,7 +97,7 @@ else if (isCollection(declaration)) { if (adapterType != null) { return convert(adapterType.getAdaptingType()); } - if (declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) { + if (RecordCompatibility.isClassOrRecord(declaration)) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java b/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java index 71fd508ab..21a61ed50 100644 --- a/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java +++ b/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java @@ -18,6 +18,7 @@ import com.webcohesion.enunciate.api.datatype.DataTypeReference; import com.webcohesion.enunciate.api.resources.Entity; import com.webcohesion.enunciate.api.resources.MediaTypeDescriptor; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.ClientName; @@ -125,7 +126,7 @@ else if (isCollection(declaration)) { if (adapterType != null) { return convert(adapterType.getAdaptingType()); } - if (declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) { + if (RecordCompatibility.isRecord(declaration)) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/gwt-json-overlay/src/main/java/com/webcohesion/enunciate/modules/gwt_json_overlay/ClientClassnameForMethod.java b/gwt-json-overlay/src/main/java/com/webcohesion/enunciate/modules/gwt_json_overlay/ClientClassnameForMethod.java index 6b421a657..e3c888317 100644 --- a/gwt-json-overlay/src/main/java/com/webcohesion/enunciate/modules/gwt_json_overlay/ClientClassnameForMethod.java +++ b/gwt-json-overlay/src/main/java/com/webcohesion/enunciate/modules/gwt_json_overlay/ClientClassnameForMethod.java @@ -18,6 +18,7 @@ import com.webcohesion.enunciate.api.datatype.DataTypeReference; import com.webcohesion.enunciate.api.resources.Entity; import com.webcohesion.enunciate.api.resources.MediaTypeDescriptor; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; import com.webcohesion.enunciate.javac.decorations.type.DecoratedDeclaredType; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; @@ -117,7 +118,7 @@ else if (isCollection(declaration)) { if (adaptingType != null) { return convert(adaptingType); } - if (declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) { + if (RecordCompatibility.isRecord(declaration)) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/JacksonModule.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/JacksonModule.java index 582135d52..a9fe37b55 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/JacksonModule.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/JacksonModule.java @@ -21,6 +21,7 @@ import com.webcohesion.enunciate.CompletionFailureException; import com.webcohesion.enunciate.EnunciateContext; import com.webcohesion.enunciate.api.ApiRegistry; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.Ignore; import com.webcohesion.enunciate.module.*; @@ -216,7 +217,7 @@ protected void addPotentialJacksonElement(Element declaration, LinkedList getAllAccessors() { static DeclaredType refineType(DecoratedProcessingEnvironment env, DecoratedElement element, Class annotation, Function> refiner) { Element elt = element; - while (elt != null && elt.getKind() != ElementKind.CLASS && elt.getKind() != ElementKind.INTERFACE && !elt.getKind().name().equals("RECORD")) { + while (elt != null && elt.getKind() != ElementKind.CLASS && elt.getKind() != ElementKind.INTERFACE && !RecordCompatibility.isRecord(elt)) { elt = elt.getEnclosingElement(); } if (elt == null) { diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/types/JsonTypeVisitor.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/types/JsonTypeVisitor.java index 8fd18b184..f52781e34 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/types/JsonTypeVisitor.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/types/JsonTypeVisitor.java @@ -17,6 +17,7 @@ import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.Annotations; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; @@ -121,7 +122,7 @@ public JsonType visitDeclared(DeclaredType declaredType, Context context) { return wrapAsNeeded(componentType.accept(this, new Context(context.context, false, true, context.stack)), context); } else { - String[] kinds = {ElementKind.CLASS.name(), ElementKind.ENUM.name(), ElementKind.INTERFACE.name(), "RECORD"}; + String[] kinds = {ElementKind.CLASS.name(), ElementKind.ENUM.name(), ElementKind.INTERFACE.name(), RecordCompatibility.KIND_RECORD}; if (Arrays.binarySearch(kinds, declaredElement.getKind().name()) >= 0) { JsonType knownType = context.getContext().getKnownType(declaredElement); if (knownType != null) { diff --git a/java-json-client/src/main/java/com/webcohesion/enunciate/modules/java_json_client/ClientClassnameForMethod.java b/java-json-client/src/main/java/com/webcohesion/enunciate/modules/java_json_client/ClientClassnameForMethod.java index d4597625d..895a544e5 100644 --- a/java-json-client/src/main/java/com/webcohesion/enunciate/modules/java_json_client/ClientClassnameForMethod.java +++ b/java-json-client/src/main/java/com/webcohesion/enunciate/modules/java_json_client/ClientClassnameForMethod.java @@ -18,6 +18,7 @@ import com.webcohesion.enunciate.api.datatype.DataTypeReference; import com.webcohesion.enunciate.api.resources.Entity; import com.webcohesion.enunciate.api.resources.MediaTypeDescriptor; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.ClientName; @@ -94,7 +95,7 @@ public String convert(TypeElement declaration) throws TemplateModelException { if (adaptingType != null) { return convert(adaptingType); } - if (declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) { + if (RecordCompatibility.isClassOrRecord(declaration)) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/java-xml-client/src/main/java/com/webcohesion/enunciate/modules/java_xml_client/ClientClassnameForMethod.java b/java-xml-client/src/main/java/com/webcohesion/enunciate/modules/java_xml_client/ClientClassnameForMethod.java index 5a2170a4f..b5a94ca8d 100644 --- a/java-xml-client/src/main/java/com/webcohesion/enunciate/modules/java_xml_client/ClientClassnameForMethod.java +++ b/java-xml-client/src/main/java/com/webcohesion/enunciate/modules/java_xml_client/ClientClassnameForMethod.java @@ -18,6 +18,7 @@ import com.webcohesion.enunciate.api.datatype.DataTypeReference; import com.webcohesion.enunciate.api.resources.Entity; import com.webcohesion.enunciate.api.resources.MediaTypeDescriptor; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.ClientName; @@ -110,7 +111,7 @@ public String convert(TypeElement declaration) throws TemplateModelException { if (adapterType != null) { return convert(adapterType.getAdaptingType()); } - if (declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) { + if (RecordCompatibility.isClassOrRecord(declaration)) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java index 2eed1fa2f..087ee8ce3 100644 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java @@ -1,14 +1,15 @@ package com.webcohesion.enunciate.javac; import javax.lang.model.element.Element; -import javax.lang.model.element.TypeElement; -import java.security.PublicKey; +import javax.lang.model.element.ElementKind; /** * Aids in adding record compatibility for JDK < 16. */ - public final class RecordCompatibility { + public static final String KIND_RECORD = "RECORD"; + public static final String KIND_RECORD_COMPONENT = "RECORD_COMPONENT"; + private RecordCompatibility() { } @@ -19,7 +20,7 @@ private RecordCompatibility() { * @return true if it's a record component */ public static boolean isRecordComponent(Element element) { - return element != null && element.getKind().name().equals("RECORD_COMPONENT"); + return element != null && element.getKind().name().equals(KIND_RECORD_COMPONENT); } /** @@ -28,11 +29,17 @@ public static boolean isRecordComponent(Element element) { * @param element the element to test * @return true if it's a record */ - public static boolean isRecord(TypeElement element) { - if (element.getSuperclass() == null) { - return false; - } + public static boolean isRecord(Element element) { + return element.getKind().name().equals(KIND_RECORD); + } - return element.getSuperclass().toString().equals("java.lang.Record"); + /** + * Check if the element is a class or record. + * + * @param element the element to test + * @return true if it's a class or record + */ + public static boolean isClassOrRecord(Element element) { + return element.getKind() == ElementKind.CLASS || isRecord(element); } } diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/DecoratedTypeElement.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/DecoratedTypeElement.java index c75c1fcc6..1e75c4251 100644 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/DecoratedTypeElement.java +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/DecoratedTypeElement.java @@ -15,6 +15,7 @@ */ package com.webcohesion.enunciate.javac.decorations.element; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; import com.webcohesion.enunciate.javac.decorations.ElementDecorator; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; @@ -151,7 +152,7 @@ public List enumValues() { public A getAnnotation(Class annotationType) { A annotation = super.getAnnotation(annotationType); - if (isClassOrRecord() && annotation == null && (annotationType.getAnnotation(Inherited.class) != null) && (getSuperclass() instanceof DeclaredType)) { + if (RecordCompatibility.isRecord(this) && annotation == null && (annotationType.getAnnotation(Inherited.class) != null) && (getSuperclass() instanceof DeclaredType)) { TypeElement superDecl = (TypeElement) ((DeclaredType) getSuperclass()).asElement(); if ((superDecl != null) && (!Object.class.getName().equals(superDecl.getQualifiedName().toString()))) { return superDecl.getAnnotation(annotationType); @@ -214,10 +215,6 @@ protected List loadEnumConstants() { return constants; } - public boolean isClassOrRecord() { - return getKind() == ElementKind.CLASS || getKind().name().equals("RECORD"); - } - public boolean isInterface() { return getKind() == ElementKind.INTERFACE; } diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/type/DecoratedTypeMirror.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/type/DecoratedTypeMirror.java index f5bfff915..2faf34785 100644 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/type/DecoratedTypeMirror.java +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/type/DecoratedTypeMirror.java @@ -15,6 +15,7 @@ */ package com.webcohesion.enunciate.javac.decorations.type; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; import com.webcohesion.enunciate.javac.decorations.ElementDecorator; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecoration; @@ -148,7 +149,7 @@ public boolean isClass() { private boolean isClassOrRecord() { Element element = ((DeclaredType) this.delegate).asElement(); - return element.getKind() == ElementKind.CLASS || element.getKind().name().equals("RECORD"); + return RecordCompatibility.isClassOrRecord(element); } public boolean isDeclared() { diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java index 28d7cfe4a..326b135a0 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java @@ -18,6 +18,7 @@ import com.webcohesion.enunciate.CompletionFailureException; import com.webcohesion.enunciate.EnunciateContext; import com.webcohesion.enunciate.EnunciateException; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; import com.webcohesion.enunciate.javac.decorations.type.DecoratedDeclaredType; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; @@ -473,7 +474,7 @@ protected void add(LocalElementDeclaration led, LinkedList stack) { protected void addReferencedTypeDefinitions(LocalElementDeclaration led, LinkedList stack) { addSeeAlsoTypeDefinitions(led, stack); DecoratedTypeElement scope = led.getElementScope(); - if (scope != null && (scope.getKind() == ElementKind.CLASS || scope.getKind().name().equals("RECORD")) && !isKnownTypeDefinition(scope)) { + if (scope != null && (RecordCompatibility.isClassOrRecord(scope)) && !isKnownTypeDefinition(scope)) { add(createTypeDefinition(scope), stack); } TypeElement typeElement = null; @@ -485,7 +486,7 @@ protected void addReferencedTypeDefinitions(LocalElementDeclaration led, LinkedL } } - if (scope != null && (scope.getKind() == ElementKind.CLASS || scope.getKind().name().equals("RECORD")) && !isKnownTypeDefinition(typeElement)) { + if (scope != null && (RecordCompatibility.isClassOrRecord(scope)) && !isKnownTypeDefinition(typeElement)) { add(createTypeDefinition(typeElement), stack); } } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/JaxbModule.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/JaxbModule.java index 328b983ef..0a6f74090 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/JaxbModule.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/JaxbModule.java @@ -18,6 +18,7 @@ import com.webcohesion.enunciate.CompletionFailureException; import com.webcohesion.enunciate.EnunciateContext; import com.webcohesion.enunciate.api.ApiRegistry; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.Ignore; import com.webcohesion.enunciate.module.*; @@ -160,7 +161,7 @@ else if (!this.jaxbContext.isKnownTypeDefinition((TypeElement) declaration) && i } protected boolean isExplicitTypeDefinition(Element declaration) { - if (declaration.getKind() != ElementKind.CLASS && declaration.getKind() != ElementKind.ENUM && !declaration.getKind().name().equals("RECORD")) { + if (declaration.getKind() != ElementKind.CLASS && declaration.getKind() != ElementKind.ENUM && !RecordCompatibility.isRecord(declaration)) { debug("%s isn't a potential JAXB type because it's not a class or an enum.", declaration); return false; } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/types/XmlTypeVisitor.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/types/XmlTypeVisitor.java index 7ac6c89bf..8e9684163 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/types/XmlTypeVisitor.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/types/XmlTypeVisitor.java @@ -16,6 +16,7 @@ package com.webcohesion.enunciate.modules.jaxb.model.types; import com.webcohesion.enunciate.EnunciateException; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.modules.jaxb.EnunciateJaxbContext; import com.webcohesion.enunciate.modules.jaxb.model.TypeDefinition; import com.webcohesion.enunciate.modules.jaxb.model.adapters.AdapterType; @@ -75,7 +76,7 @@ public XmlType visitDeclared(DeclaredType declaredType, Context context) { return new MapXmlType(keyType, valueType); } else { - String[] kinds = {ElementKind.CLASS.name(), ElementKind.ENUM.name(), "RECORD"}; + String[] kinds = {ElementKind.CLASS.name(), ElementKind.ENUM.name(), RecordCompatibility.KIND_RECORD}; if(Arrays.binarySearch(kinds,declaredElement.getKind().name()) >=0) { XmlType knownType = context.getContext().getKnownType(declaredElement); if (knownType != null) { diff --git a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java index ab98fed95..d6b74c8af 100644 --- a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java +++ b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java @@ -17,6 +17,7 @@ import com.webcohesion.enunciate.facets.Facet; import com.webcohesion.enunciate.facets.HasFacets; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; import com.webcohesion.enunciate.javac.decorations.element.PropertyElement; import com.webcohesion.enunciate.javac.decorations.type.TypeVariableContext; @@ -121,7 +122,7 @@ protected List getSubresourceLocators(TypeElement delegate, } - if (delegate.getKind() == ElementKind.CLASS || delegate.getKind().name().equals("RECORD")) { + if (RecordCompatibility.isClassOrRecord(delegate)) { TypeMirror superclass = delegate.getSuperclass(); if (superclass instanceof DeclaredType && ((DeclaredType)superclass).asElement() != null) { List superMethods = getSubresourceLocators((TypeElement) ((DeclaredType) superclass).asElement(), variableContext, context); @@ -181,7 +182,7 @@ protected List getResourceMethods(final TypeElement delegate, Ty } } - if (delegate.getKind() == ElementKind.CLASS || delegate.getKind().name().equals("RECORD")) { + if (RecordCompatibility.isRecordComponent(delegate)) { TypeMirror superclass = delegate.getSuperclass(); if (superclass instanceof DeclaredType && ((DeclaredType)superclass).asElement() != null) { DeclaredType declared = (DeclaredType) superclass; @@ -223,7 +224,7 @@ protected Set getResourceParameters(TypeElement delegate, Enu } } - if ((delegate.getKind() == ElementKind.CLASS || delegate.getKind().name().equals("RECORD")) && delegate.getSuperclass() instanceof DeclaredType) { + if (RecordCompatibility.isClassOrRecord(delegate) && delegate.getSuperclass() instanceof DeclaredType) { Set superParams = getResourceParameters((TypeElement) ((DeclaredType) delegate.getSuperclass()).asElement(), context); for (ResourceParameter superParam : superParams) { if (!isHidden(superParam, resourceParameters)) { diff --git a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java index aa1369b46..69d9ebfe9 100644 --- a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java +++ b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java @@ -15,6 +15,7 @@ */ package com.webcohesion.enunciate.modules.jaxrs.model; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; import com.webcohesion.enunciate.javac.decorations.ElementDecorator; import com.webcohesion.enunciate.javac.decorations.element.*; @@ -265,7 +266,7 @@ else if (isBeanParameter(property)) { } } - if (typeDeclaration.getKind() == ElementKind.CLASS || typeDeclaration.getKind().name().equals("RECORD")) { + if (RecordCompatibility.isClassOrRecord(typeDeclaration)) { gatherFormBeanParameters(typeDeclaration.getSuperclass(), beanParams, context); } } diff --git a/jaxws/src/main/java/com/webcohesion/enunciate/modules/jaxws/model/EndpointInterface.java b/jaxws/src/main/java/com/webcohesion/enunciate/modules/jaxws/model/EndpointInterface.java index 702098101..4b5cc9495 100644 --- a/jaxws/src/main/java/com/webcohesion/enunciate/modules/jaxws/model/EndpointInterface.java +++ b/jaxws/src/main/java/com/webcohesion/enunciate/modules/jaxws/model/EndpointInterface.java @@ -18,6 +18,7 @@ import com.webcohesion.enunciate.EnunciateException; import com.webcohesion.enunciate.facets.Facet; import com.webcohesion.enunciate.facets.HasFacets; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.TypeElementComparator; import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; import com.webcohesion.enunciate.javac.decorations.type.TypeVariableContext; @@ -76,7 +77,7 @@ public EndpointInterface(TypeElement delegate, Set implementa annotation = getAnnotation(jakarta.jws.WebService.class); impls = new ArrayList(); if (annotation != null) { - if (isClassOrRecord()) { + if (RecordCompatibility.isClassOrRecord(this)) { //if the declaration is a class, the endpoint interface is implied... impls.add(new EndpointImplementation(getDelegate(), this, context)); } @@ -105,7 +106,7 @@ public EndpointInterface(TypeElement delegate, Set implementa } } - if (delegate.getKind() == ElementKind.CLASS || delegate.getKind().name().equals("RECORD")) { + if (RecordCompatibility.isClassOrRecord(delegate)) { //the spec says we need to consider superclass methods, too... TypeMirror superclass = delegate.getSuperclass(); if (superclass instanceof DeclaredType) { @@ -310,7 +311,7 @@ public Collection getEndpointImplementations() { * A quick check to see if a declaration is an endpoint implementation. */ protected boolean isEndpointImplementation(TypeElement declaration) { - if ((declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) && !declaration.getQualifiedName().equals(getQualifiedName())) { + if (RecordCompatibility.isClassOrRecord(declaration) && !declaration.getQualifiedName().equals(getQualifiedName())) { WebService webServiceInfo = declaration.getAnnotation(WebService.class); return webServiceInfo != null && getQualifiedName().toString().equals(webServiceInfo.endpointInterface()); } diff --git a/obj-c-xml-client/src/main/java/com/webcohesion/enunciate/modules/objc_client/ClientClassnameForMethod.java b/obj-c-xml-client/src/main/java/com/webcohesion/enunciate/modules/objc_client/ClientClassnameForMethod.java index 9f849ffe1..b0d29f0fc 100644 --- a/obj-c-xml-client/src/main/java/com/webcohesion/enunciate/modules/objc_client/ClientClassnameForMethod.java +++ b/obj-c-xml-client/src/main/java/com/webcohesion/enunciate/modules/objc_client/ClientClassnameForMethod.java @@ -15,6 +15,7 @@ */ package com.webcohesion.enunciate.modules.objc_client; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; import com.webcohesion.enunciate.metadata.ClientName; import com.webcohesion.enunciate.modules.jaxb.EnunciateJaxbContext; @@ -95,7 +96,7 @@ else if (isCollection(declaration)) { if (adapterType != null) { return convert(adapterType.getAdaptingType()); } - if (declaration.getKind() == ElementKind.CLASS || declaration.getKind().name().equals("RECORD")) { + if (RecordCompatibility.isClassOrRecord(declaration)) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java index 0dc0255b6..f70bf3d99 100644 --- a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java +++ b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java @@ -15,6 +15,7 @@ */ package com.webcohesion.enunciate.modules.spring_web.model; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; import com.webcohesion.enunciate.javac.decorations.ElementDecorator; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; @@ -196,7 +197,7 @@ private static void gatherFormObjectParameters(TypeMirror type, ArrayList getRequestMappings(final TypeElement delegate, Ty } } - if (delegate.getKind() == ElementKind.CLASS || delegate.getKind().name().equals("RECORD")) { + if (RecordCompatibility.isClassOrRecord(delegate)) { TypeMirror superclass = delegate.getSuperclass(); if (superclass instanceof DeclaredType && ((DeclaredType) superclass).asElement() != null) { DeclaredType declared = (DeclaredType) superclass; diff --git a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/SpringControllerAdvice.java b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/SpringControllerAdvice.java index 6b2f2b2de..8cd8195b4 100644 --- a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/SpringControllerAdvice.java +++ b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/SpringControllerAdvice.java @@ -15,6 +15,7 @@ */ package com.webcohesion.enunciate.modules.spring_web.model; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; import com.webcohesion.enunciate.javac.decorations.type.TypeVariableContext; import com.webcohesion.enunciate.modules.spring_web.EnunciateSpringWebContext; @@ -187,7 +188,7 @@ protected List findRequestMappingAdvice(RequestMapping req } } - if (controllerAdvice.getKind() == ElementKind.CLASS || controllerAdvice.getKind().name().equals("RECORD")) { + if (RecordCompatibility.isClassOrRecord(controllerAdvice)) { TypeMirror superclass = controllerAdvice.getSuperclass(); if (superclass instanceof DeclaredType && ((DeclaredType)superclass).asElement() != null) { DeclaredType declared = (DeclaredType) superclass; From 22627f8ba96507b7c31b4a05ea1728da2d2e9c61 Mon Sep 17 00:00:00 2001 From: Jesenko Mehmedbasic Date: Tue, 17 Oct 2023 13:30:12 +0200 Subject: [PATCH 10/11] Use RecordCompatibility constant to check for java.lang.Record equality --- .../c_client/ClientClassnameForMethod.java | 2 +- .../freemarker/ClientClassnameForMethod.java | 5 +-- .../ClientClassnameForMethod.java | 2 +- .../jackson/EnunciateJacksonContext.java | 3 +- .../jackson/model/ObjectTypeDefinition.java | 32 ++++++++++++------- .../modules/jackson/model/TypeDefinition.java | 2 +- .../enunciate/javac/RecordCompatibility.java | 1 + .../ClientClassnameForMethod.java | 3 +- .../modules/jaxb/EnunciateJaxbContext.java | 2 +- .../jaxb/model/ComplexTypeDefinition.java | 3 +- 10 files changed, 34 insertions(+), 21 deletions(-) diff --git a/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java b/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java index 22ce6c3ed..5aa9081d0 100644 --- a/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java +++ b/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java @@ -79,7 +79,7 @@ public ClientClassnameForMethod(Map conversions, EnunciateJaxbCo classConversions.put(javax.xml.datatype.Duration.class.getName(), "xmlChar"); classConversions.put(jakarta.xml.bind.JAXBElement.class.getName(), "struct xmlBasicNode"); classConversions.put(Object.class.getName(), "struct xmlBasicNode"); - classConversions.put("java.lang.Record", "struct xmlBasicNode"); + classConversions.put(RecordCompatibility.CLASS_RECORD, "struct xmlBasicNode"); classConversions.putAll(conversions); } diff --git a/core/src/main/java/com/webcohesion/enunciate/util/freemarker/ClientClassnameForMethod.java b/core/src/main/java/com/webcohesion/enunciate/util/freemarker/ClientClassnameForMethod.java index 6cc14dd17..2685afdc3 100644 --- a/core/src/main/java/com/webcohesion/enunciate/util/freemarker/ClientClassnameForMethod.java +++ b/core/src/main/java/com/webcohesion/enunciate/util/freemarker/ClientClassnameForMethod.java @@ -16,6 +16,7 @@ package com.webcohesion.enunciate.util.freemarker; import com.webcohesion.enunciate.EnunciateContext; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.util.HasClientConvertibleType; import freemarker.template.TemplateModelException; @@ -93,7 +94,7 @@ else if (typeMirror instanceof TypeVariable) { conversion = super.convert(typeMirror); boolean isArray = typeMirror.getKind() == TypeKind.ARRAY; - if (typeMirror instanceof DeclaredType && !"java.lang.Object".equals(conversion) && !"java.lang.Record".equals(conversion)) { + if (typeMirror instanceof DeclaredType && !"java.lang.Object".equals(conversion) && !RecordCompatibility.CLASS_RECORD.equals(conversion)) { conversion += convertDeclaredTypeArguments(((DeclaredType) typeMirror).getTypeArguments()); } @@ -162,4 +163,4 @@ protected String getPackageSeparator() { public String convert(PackageElement packageDeclaration) { throw new UnsupportedOperationException("packages don't have a classname."); } -} \ No newline at end of file +} diff --git a/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java b/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java index 21a61ed50..e1e9ff253 100644 --- a/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java +++ b/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java @@ -87,7 +87,7 @@ public ClientClassnameForMethod(Map conversions, EnunciateJaxbCo classConversions.put(javax.xml.datatype.Duration.class.getName(), "TimeSpan?"); classConversions.put(jakarta.xml.bind.JAXBElement.class.getName(), "object"); classConversions.put(Object.class.getName(), "object"); - classConversions.put("java.lang.Record", "object"); + classConversions.put(RecordCompatibility.CLASS_RECORD, "object"); } @Override diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java index c590ba5fb..ad32795f0 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java @@ -24,6 +24,7 @@ import com.webcohesion.enunciate.CompletionFailureException; import com.webcohesion.enunciate.EnunciateContext; import com.webcohesion.enunciate.EnunciateException; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; import com.webcohesion.enunciate.javac.decorations.SourcePosition; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; @@ -226,7 +227,7 @@ protected Map loadKnownTypes() { knownTypes.put(java.net.URI.class.getName(), KnownJsonType.STRING); knownTypes.put(java.net.URL.class.getName(), KnownJsonType.STRING); knownTypes.put(java.lang.Object.class.getName(), KnownJsonType.OBJECT); - knownTypes.put("java.lang.Record", KnownJsonType.OBJECT); + knownTypes.put(RecordCompatibility.CLASS_RECORD, KnownJsonType.OBJECT); knownTypes.put(java.io.Serializable.class.getName(), KnownJsonType.OBJECT); knownTypes.put(byte[].class.getName(), KnownJsonType.STRING); knownTypes.put(java.nio.ByteBuffer.class.getName(), KnownJsonType.STRING); diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/ObjectTypeDefinition.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/ObjectTypeDefinition.java index 2a5753841..28785d729 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/ObjectTypeDefinition.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/ObjectTypeDefinition.java @@ -1,12 +1,12 @@ /** * Copyright © 2006-2016 Web Cohesion (info@webcohesion.com) - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,16 +16,18 @@ package com.webcohesion.enunciate.modules.jackson.model; import com.fasterxml.jackson.annotation.JsonRootName; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.modules.jackson.EnunciateJacksonContext; import com.webcohesion.enunciate.modules.jackson.model.types.JsonType; import com.webcohesion.enunciate.modules.jackson.model.types.JsonTypeFactory; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; -import jakarta.xml.bind.annotation.XmlRootElement; -import jakarta.xml.bind.annotation.XmlType; /** * A type definition for a json type. @@ -43,7 +45,7 @@ public JsonType getSupertype() { if (superclass == null || superclass.getKind() == TypeKind.NONE) { return null; } - else if (superclass instanceof DeclaredType && (((TypeElement)((DeclaredType)superclass).asElement()).getQualifiedName().toString().equals(Object.class.getName()) || ((TypeElement)((DeclaredType)superclass).asElement()).getQualifiedName().toString().equals("java.lang.Record") || context.isIgnored((((DeclaredType)superclass).asElement())) || context.isCollapseTypeHierarchy())) { + else if (superclass instanceof DeclaredType && (isClasOrRecord(superclass) || context.isIgnored(((DeclaredType) superclass).asElement()) || context.isCollapseTypeHierarchy())) { return null; } else { @@ -51,6 +53,12 @@ else if (superclass instanceof DeclaredType && (((TypeElement)((DeclaredType)sup } } + private boolean isClasOrRecord(TypeMirror superclass) { + TypeElement typeElement = (TypeElement) ((DeclaredType) superclass).asElement(); + String qualifiedName = typeElement.getQualifiedName().toString(); + return qualifiedName.equals(Object.class.getName()) || qualifiedName.equals(RecordCompatibility.CLASS_RECORD); + } + @Override public boolean isSimple() { return false; @@ -70,11 +78,11 @@ public boolean isBaseObject() { TypeElement superDeclaration = (TypeElement) this.env.getTypeUtils().asElement(superclass); return superDeclaration == null - || Object.class.getName().equals(superDeclaration.getQualifiedName().toString()) - || Enum.class.getName().equals(superDeclaration.getQualifiedName().toString()) - || "java.lang.Record".equals(superDeclaration.getQualifiedName().toString()) - || this.context.isCollapseTypeHierarchy() - || this.context.isIgnored(superDeclaration); + || Object.class.getName().equals(superDeclaration.getQualifiedName().toString()) + || Enum.class.getName().equals(superDeclaration.getQualifiedName().toString()) + || RecordCompatibility.CLASS_RECORD.equals(superDeclaration.getQualifiedName().toString()) + || this.context.isCollapseTypeHierarchy() + || this.context.isIgnored(superDeclaration); } public String getJsonRootName() { diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java index 27c706a90..bd8b99574 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java @@ -193,7 +193,7 @@ protected AccessorBag loadPotentialAccessors(AccessorFilter filter) { */ protected void aggregatePotentialAccessors(AccessorBag bag, DecoratedTypeElement clazz, AccessorFilter filter, boolean inlineAccessorsOfSuperclasses) { String fqn = clazz.getQualifiedName().toString(); - if (Object.class.getName().equals(fqn) || Enum.class.getName().equals(fqn) || "java.lang.Record".equals(fqn)) { + if (Object.class.getName().equals(fqn) || Enum.class.getName().equals(fqn) || RecordCompatibility.CLASS_RECORD.equals(fqn)) { return; } diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java index 087ee8ce3..bdf03926c 100644 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java @@ -9,6 +9,7 @@ public final class RecordCompatibility { public static final String KIND_RECORD = "RECORD"; public static final String KIND_RECORD_COMPONENT = "RECORD_COMPONENT"; + public static final String CLASS_RECORD = "java.lang.Record"; private RecordCompatibility() { } diff --git a/javascript-client/src/main/java/com/webcohesion/enunciate/modules/javascript_client/ClientClassnameForMethod.java b/javascript-client/src/main/java/com/webcohesion/enunciate/modules/javascript_client/ClientClassnameForMethod.java index 3eeeded0c..73aa76ece 100644 --- a/javascript-client/src/main/java/com/webcohesion/enunciate/modules/javascript_client/ClientClassnameForMethod.java +++ b/javascript-client/src/main/java/com/webcohesion/enunciate/modules/javascript_client/ClientClassnameForMethod.java @@ -19,6 +19,7 @@ import com.webcohesion.enunciate.api.datatype.DataTypeReference; import com.webcohesion.enunciate.api.resources.Entity; import com.webcohesion.enunciate.api.resources.MediaTypeDescriptor; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.ClientName; @@ -84,7 +85,7 @@ public ClientClassnameForMethod(Map conversions, EnunciateJackso classConversions.put(javax.xml.datatype.Duration.class.getName(), "String"); classConversions.put(jakarta.xml.bind.JAXBElement.class.getName(), "Object"); classConversions.put(Object.class.getName(), "Object"); - classConversions.put("java.lang.Record", "Object"); + classConversions.put(RecordCompatibility.CLASS_RECORD, "Object"); } @Override diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java index 326b135a0..befc22404 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java @@ -192,7 +192,7 @@ protected Map loadKnownTypes() { knownTypes.put(java.net.URI.class.getName(), KnownXmlType.STRING); knownTypes.put(javax.xml.datatype.Duration.class.getName(), KnownXmlType.DURATION); knownTypes.put(java.lang.Object.class.getName(), KnownXmlType.ANY_TYPE); - knownTypes.put("java.lang.Record", KnownXmlType.ANY_TYPE); + knownTypes.put(RecordCompatibility.CLASS_RECORD, KnownXmlType.ANY_TYPE); knownTypes.put(java.io.Serializable.class.getName(), KnownXmlType.ANY_TYPE); knownTypes.put(byte[].class.getName(), KnownXmlType.BASE64_BINARY); knownTypes.put(java.nio.ByteBuffer.class.getName(), KnownXmlType.BASE64_BINARY); diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/ComplexTypeDefinition.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/ComplexTypeDefinition.java index 8e271da8d..ccc352921 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/ComplexTypeDefinition.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/ComplexTypeDefinition.java @@ -15,6 +15,7 @@ */ package com.webcohesion.enunciate.modules.jaxb.model; +import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.modules.jaxb.EnunciateJaxbContext; import com.webcohesion.enunciate.modules.jaxb.model.types.KnownXmlType; import com.webcohesion.enunciate.modules.jaxb.model.types.XmlType; @@ -114,7 +115,7 @@ public boolean isBaseObject() { TypeElement superDeclaration = (TypeElement) this.env.getTypeUtils().asElement(superclass); return superDeclaration == null || Object.class.getName().equals(superDeclaration.getQualifiedName().toString()) - || "java.lang.Record".equals(superDeclaration.getQualifiedName().toString()) + || RecordCompatibility.CLASS_RECORD.equals(superDeclaration.getQualifiedName().toString()) || isXmlTransient(superDeclaration); } From 8bdffe313e405d0ca411fac77b8ad16caffdeb84 Mon Sep 17 00:00:00 2001 From: Jesenko Mehmedbasic Date: Tue, 17 Oct 2023 13:42:01 +0200 Subject: [PATCH 11/11] Assume JDK 17 is available, remove diffs with origin in preparation for PR. --- .../c_client/ClientClassnameForMethod.java | 8 ++-- .../freemarker/ClientClassnameForMethod.java | 3 +- .../ClientClassnameForMethod.java | 8 ++-- examples/full-api-edge-cases/pom.xml | 5 -- examples/jackson2-api-lombok/pom.xml | 5 -- examples/jackson2-api/pom.xml | 5 -- examples/spring-petclinic/pom.xml | 5 -- .../ClientClassnameForMethod.java | 5 +- .../jackson/EnunciateJacksonContext.java | 4 +- .../modules/jackson/JacksonModule.java | 3 +- .../modules/jackson/model/AccessorFilter.java | 5 +- .../jackson/model/ObjectTypeDefinition.java | 26 +++++------ .../modules/jackson/model/TypeDefinition.java | 10 ++-- .../jackson/model/types/JsonTypeVisitor.java | 26 +++++------ .../ClientClassnameForMethod.java | 4 +- .../ClientClassnameForMethod.java | 4 +- .../enunciate/javac/CompatElementFilter.java | 36 --------------- .../enunciate/javac/RecordCompatibility.java | 46 ------------------- .../javac/decorations/DecoratedElements.java | 3 +- .../element/DecoratedTypeElement.java | 4 +- .../decorations/element/ElementUtils.java | 35 ++++++++++++++ .../decorations/type/DecoratedTypeMirror.java | 4 +- .../ClientClassnameForMethod.java | 3 +- .../modules/jaxb/EnunciateJaxbContext.java | 8 ++-- .../enunciate/modules/jaxb/JaxbModule.java | 3 +- .../modules/jaxb/model/Accessor.java | 4 +- .../jaxb/model/ComplexTypeDefinition.java | 3 +- .../modules/jaxb/model/TypeDefinition.java | 4 +- .../jaxb/model/types/XmlTypeVisitor.java | 26 +++++------ .../modules/jaxrs/model/Resource.java | 11 ++--- .../jaxrs/model/ResourceParameter.java | 6 +-- .../jaxws/model/EndpointInterface.java | 8 ++-- .../objc_client/ClientClassnameForMethod.java | 6 +-- pom.xml | 1 - rt-util/pom.xml | 1 - .../model/RequestParameterFactory.java | 7 ++- .../spring_web/model/SpringController.java | 4 +- .../model/SpringControllerAdvice.java | 4 +- 38 files changed, 131 insertions(+), 222 deletions(-) delete mode 100644 javac-support/src/main/java/com/webcohesion/enunciate/javac/CompatElementFilter.java delete mode 100644 javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java diff --git a/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java b/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java index 5aa9081d0..1fd2ea318 100644 --- a/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java +++ b/c-xml-client/src/main/java/com/webcohesion/enunciate/modules/c_client/ClientClassnameForMethod.java @@ -15,8 +15,8 @@ */ package com.webcohesion.enunciate.modules.c_client; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.ClientName; import com.webcohesion.enunciate.modules.jaxb.EnunciateJaxbContext; @@ -28,7 +28,7 @@ import freemarker.template.TemplateModelException; import jakarta.activation.DataHandler; -import javax.lang.model.element.ElementKind; + import javax.lang.model.element.TypeElement; import javax.lang.model.type.*; import jakarta.xml.bind.JAXBElement; @@ -79,7 +79,7 @@ public ClientClassnameForMethod(Map conversions, EnunciateJaxbCo classConversions.put(javax.xml.datatype.Duration.class.getName(), "xmlChar"); classConversions.put(jakarta.xml.bind.JAXBElement.class.getName(), "struct xmlBasicNode"); classConversions.put(Object.class.getName(), "struct xmlBasicNode"); - classConversions.put(RecordCompatibility.CLASS_RECORD, "struct xmlBasicNode"); + classConversions.put(Record.class.getName(), "struct xmlBasicNode"); classConversions.putAll(conversions); } @@ -97,7 +97,7 @@ else if (isCollection(declaration)) { if (adapterType != null) { return convert(adapterType.getAdaptingType()); } - if (RecordCompatibility.isClassOrRecord(declaration)) { + if (ElementUtils.isClassOrRecord(declaration)) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/core/src/main/java/com/webcohesion/enunciate/util/freemarker/ClientClassnameForMethod.java b/core/src/main/java/com/webcohesion/enunciate/util/freemarker/ClientClassnameForMethod.java index 2685afdc3..6ce3cb516 100644 --- a/core/src/main/java/com/webcohesion/enunciate/util/freemarker/ClientClassnameForMethod.java +++ b/core/src/main/java/com/webcohesion/enunciate/util/freemarker/ClientClassnameForMethod.java @@ -16,7 +16,6 @@ package com.webcohesion.enunciate.util.freemarker; import com.webcohesion.enunciate.EnunciateContext; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.util.HasClientConvertibleType; import freemarker.template.TemplateModelException; @@ -94,7 +93,7 @@ else if (typeMirror instanceof TypeVariable) { conversion = super.convert(typeMirror); boolean isArray = typeMirror.getKind() == TypeKind.ARRAY; - if (typeMirror instanceof DeclaredType && !"java.lang.Object".equals(conversion) && !RecordCompatibility.CLASS_RECORD.equals(conversion)) { + if (typeMirror instanceof DeclaredType && !Object.class.getName().equals(conversion) && !Record.class.getName().equals(conversion)) { conversion += convertDeclaredTypeArguments(((DeclaredType) typeMirror).getTypeArguments()); } diff --git a/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java b/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java index e1e9ff253..d60141b5a 100644 --- a/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java +++ b/csharp-xml-client/src/main/java/com/webcohesion/enunciate/modules/csharp_client/ClientClassnameForMethod.java @@ -18,8 +18,8 @@ import com.webcohesion.enunciate.api.datatype.DataTypeReference; import com.webcohesion.enunciate.api.resources.Entity; import com.webcohesion.enunciate.api.resources.MediaTypeDescriptor; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.ClientName; import com.webcohesion.enunciate.modules.jaxb.EnunciateJaxbContext; @@ -35,9 +35,9 @@ import freemarker.template.TemplateModelException; import jakarta.activation.DataHandler; + import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; -import javax.lang.model.element.TypeParameterElement; import javax.lang.model.type.*; import jakarta.xml.bind.JAXBElement; import javax.xml.datatype.XMLGregorianCalendar; @@ -87,7 +87,7 @@ public ClientClassnameForMethod(Map conversions, EnunciateJaxbCo classConversions.put(javax.xml.datatype.Duration.class.getName(), "TimeSpan?"); classConversions.put(jakarta.xml.bind.JAXBElement.class.getName(), "object"); classConversions.put(Object.class.getName(), "object"); - classConversions.put(RecordCompatibility.CLASS_RECORD, "object"); + classConversions.put(Record.class.getName(), "object"); } @Override @@ -126,7 +126,7 @@ else if (isCollection(declaration)) { if (adapterType != null) { return convert(adapterType.getAdaptingType()); } - if (RecordCompatibility.isRecord(declaration)) { + if (ElementUtils.isClassOrRecord(declaration)) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/examples/full-api-edge-cases/pom.xml b/examples/full-api-edge-cases/pom.xml index ea06decd5..5998df174 100644 --- a/examples/full-api-edge-cases/pom.xml +++ b/examples/full-api-edge-cases/pom.xml @@ -15,11 +15,6 @@ - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - org.apache.maven.plugins maven-surefire-plugin diff --git a/examples/jackson2-api-lombok/pom.xml b/examples/jackson2-api-lombok/pom.xml index 227518fb7..4392658fd 100644 --- a/examples/jackson2-api-lombok/pom.xml +++ b/examples/jackson2-api-lombok/pom.xml @@ -15,11 +15,6 @@ - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - com.webcohesion.enunciate enunciate-maven-plugin diff --git a/examples/jackson2-api/pom.xml b/examples/jackson2-api/pom.xml index 80e28ac18..96a7a027f 100644 --- a/examples/jackson2-api/pom.xml +++ b/examples/jackson2-api/pom.xml @@ -15,11 +15,6 @@ - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - com.webcohesion.enunciate enunciate-maven-plugin diff --git a/examples/spring-petclinic/pom.xml b/examples/spring-petclinic/pom.xml index c0f906344..ca5adde07 100644 --- a/examples/spring-petclinic/pom.xml +++ b/examples/spring-petclinic/pom.xml @@ -21,11 +21,6 @@ - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - com.webcohesion.enunciate enunciate-maven-plugin diff --git a/gwt-json-overlay/src/main/java/com/webcohesion/enunciate/modules/gwt_json_overlay/ClientClassnameForMethod.java b/gwt-json-overlay/src/main/java/com/webcohesion/enunciate/modules/gwt_json_overlay/ClientClassnameForMethod.java index e3c888317..b4b7972e9 100644 --- a/gwt-json-overlay/src/main/java/com/webcohesion/enunciate/modules/gwt_json_overlay/ClientClassnameForMethod.java +++ b/gwt-json-overlay/src/main/java/com/webcohesion/enunciate/modules/gwt_json_overlay/ClientClassnameForMethod.java @@ -18,13 +18,12 @@ import com.webcohesion.enunciate.api.datatype.DataTypeReference; import com.webcohesion.enunciate.api.resources.Entity; import com.webcohesion.enunciate.api.resources.MediaTypeDescriptor; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.javac.decorations.type.DecoratedDeclaredType; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.ClientName; import com.webcohesion.enunciate.metadata.qname.XmlQNameEnumRef; -import com.webcohesion.enunciate.modules.jackson.EnunciateJacksonContext; import com.webcohesion.enunciate.modules.jackson.api.impl.SyntaxImpl; import com.webcohesion.enunciate.util.HasClientConvertibleType; import freemarker.template.TemplateModelException; @@ -118,7 +117,7 @@ else if (isCollection(declaration)) { if (adaptingType != null) { return convert(adaptingType); } - if (RecordCompatibility.isRecord(declaration)) { + if (ElementUtils.isClassOrRecord(declaration)) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java index ad32795f0..af1bf5044 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/EnunciateJacksonContext.java @@ -24,9 +24,7 @@ import com.webcohesion.enunciate.CompletionFailureException; import com.webcohesion.enunciate.EnunciateContext; import com.webcohesion.enunciate.EnunciateException; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; -import com.webcohesion.enunciate.javac.decorations.SourcePosition; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; import com.webcohesion.enunciate.javac.decorations.element.PropertyElement; import com.webcohesion.enunciate.javac.decorations.type.DecoratedDeclaredType; @@ -227,7 +225,7 @@ protected Map loadKnownTypes() { knownTypes.put(java.net.URI.class.getName(), KnownJsonType.STRING); knownTypes.put(java.net.URL.class.getName(), KnownJsonType.STRING); knownTypes.put(java.lang.Object.class.getName(), KnownJsonType.OBJECT); - knownTypes.put(RecordCompatibility.CLASS_RECORD, KnownJsonType.OBJECT); + knownTypes.put(Record.class.getName(), KnownJsonType.OBJECT); knownTypes.put(java.io.Serializable.class.getName(), KnownJsonType.OBJECT); knownTypes.put(byte[].class.getName(), KnownJsonType.STRING); knownTypes.put(java.nio.ByteBuffer.class.getName(), KnownJsonType.STRING); diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/JacksonModule.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/JacksonModule.java index a9fe37b55..5e154beab 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/JacksonModule.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/JacksonModule.java @@ -21,7 +21,6 @@ import com.webcohesion.enunciate.CompletionFailureException; import com.webcohesion.enunciate.EnunciateContext; import com.webcohesion.enunciate.api.ApiRegistry; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.Ignore; import com.webcohesion.enunciate.module.*; @@ -217,7 +216,7 @@ protected void addPotentialJacksonElement(Element declaration, LinkedList + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,14 +16,12 @@ package com.webcohesion.enunciate.modules.jackson.model; import com.fasterxml.jackson.annotation.JsonRootName; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.modules.jackson.EnunciateJacksonContext; import com.webcohesion.enunciate.modules.jackson.model.types.JsonType; import com.webcohesion.enunciate.modules.jackson.model.types.JsonTypeFactory; import jakarta.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.XmlType; -import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; @@ -45,7 +43,7 @@ public JsonType getSupertype() { if (superclass == null || superclass.getKind() == TypeKind.NONE) { return null; } - else if (superclass instanceof DeclaredType && (isClasOrRecord(superclass) || context.isIgnored(((DeclaredType) superclass).asElement()) || context.isCollapseTypeHierarchy())) { + else if (superclass instanceof DeclaredType && (isClassOrRecord(superclass) || context.isIgnored(((DeclaredType) superclass).asElement()) || context.isCollapseTypeHierarchy())) { return null; } else { @@ -53,10 +51,10 @@ else if (superclass instanceof DeclaredType && (isClasOrRecord(superclass) || co } } - private boolean isClasOrRecord(TypeMirror superclass) { + private boolean isClassOrRecord(TypeMirror superclass) { TypeElement typeElement = (TypeElement) ((DeclaredType) superclass).asElement(); String qualifiedName = typeElement.getQualifiedName().toString(); - return qualifiedName.equals(Object.class.getName()) || qualifiedName.equals(RecordCompatibility.CLASS_RECORD); + return qualifiedName.equals(Object.class.getName()) || qualifiedName.equals(Record.class.getName()); } @Override @@ -78,11 +76,11 @@ public boolean isBaseObject() { TypeElement superDeclaration = (TypeElement) this.env.getTypeUtils().asElement(superclass); return superDeclaration == null - || Object.class.getName().equals(superDeclaration.getQualifiedName().toString()) - || Enum.class.getName().equals(superDeclaration.getQualifiedName().toString()) - || RecordCompatibility.CLASS_RECORD.equals(superDeclaration.getQualifiedName().toString()) - || this.context.isCollapseTypeHierarchy() - || this.context.isIgnored(superDeclaration); + || Object.class.getName().equals(superDeclaration.getQualifiedName().toString()) + || Enum.class.getName().equals(superDeclaration.getQualifiedName().toString()) + || Record.class.getName().equals(superDeclaration.getQualifiedName().toString()) + || this.context.isCollapseTypeHierarchy() + || this.context.isIgnored(superDeclaration); } public String getJsonRootName() { diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java index bd8b99574..ff328339b 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/TypeDefinition.java @@ -21,7 +21,6 @@ import com.webcohesion.enunciate.EnunciateException; import com.webcohesion.enunciate.facets.Facet; import com.webcohesion.enunciate.facets.HasFacets; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.Annotations; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; @@ -33,7 +32,6 @@ import com.webcohesion.enunciate.modules.jackson.javac.ToStringValueProperty; import com.webcohesion.enunciate.util.AccessorBag; import com.webcohesion.enunciate.util.AnnotationUtils; -import com.webcohesion.enunciate.javac.CompatElementFilter; import com.webcohesion.enunciate.util.SortedList; import javax.lang.model.element.*; @@ -193,7 +191,7 @@ protected AccessorBag loadPotentialAccessors(AccessorFilter filter) { */ protected void aggregatePotentialAccessors(AccessorBag bag, DecoratedTypeElement clazz, AccessorFilter filter, boolean inlineAccessorsOfSuperclasses) { String fqn = clazz.getQualifiedName().toString(); - if (Object.class.getName().equals(fqn) || Enum.class.getName().equals(fqn) || RecordCompatibility.CLASS_RECORD.equals(fqn)) { + if (Object.class.getName().equals(fqn) || Enum.class.getName().equals(fqn) || Record.class.getName().equals(fqn)) { return; } @@ -221,10 +219,10 @@ protected void aggregatePotentialAccessors(AccessorBag bag, DecoratedTypeElement } } - List fieldElements = CompatElementFilter.fieldsOrRecordComponentsIn(clazz); + List fieldElements = ElementUtils.fieldsOrRecordComponentsIn(clazz); if (mixin != null) { //replace all mixin fields. - for (Element mixinField : CompatElementFilter.fieldsOrRecordComponentsIn(mixin)) { + for (Element mixinField : ElementUtils.fieldsOrRecordComponentsIn(mixin)) { int index = indexOf(fieldElements, mixinField.getSimpleName().toString()); if (index >= 0) { fieldElements.set(index, mixinField); @@ -602,7 +600,7 @@ public List getAllAccessors() { static DeclaredType refineType(DecoratedProcessingEnvironment env, DecoratedElement element, Class annotation, Function> refiner) { Element elt = element; - while (elt != null && elt.getKind() != ElementKind.CLASS && elt.getKind() != ElementKind.INTERFACE && !RecordCompatibility.isRecord(elt)) { + while (elt != null && elt.getKind() != ElementKind.CLASS && elt.getKind() != ElementKind.INTERFACE && elt.getKind() != ElementKind.RECORD) { elt = elt.getEnclosingElement(); } if (elt == null) { diff --git a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/types/JsonTypeVisitor.java b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/types/JsonTypeVisitor.java index f52781e34..9b43d70ac 100644 --- a/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/types/JsonTypeVisitor.java +++ b/jackson/src/main/java/com/webcohesion/enunciate/modules/jackson/model/types/JsonTypeVisitor.java @@ -17,7 +17,6 @@ import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.Annotations; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; @@ -31,11 +30,9 @@ import com.webcohesion.enunciate.util.TypeHintUtils; import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.lang.model.type.*; import javax.lang.model.util.SimpleTypeVisitor6; -import java.util.Arrays; import java.util.LinkedList; import static com.webcohesion.enunciate.javac.decorations.type.TypeMirrorUtils.getComponentType; @@ -122,17 +119,18 @@ public JsonType visitDeclared(DeclaredType declaredType, Context context) { return wrapAsNeeded(componentType.accept(this, new Context(context.context, false, true, context.stack)), context); } else { - String[] kinds = {ElementKind.CLASS.name(), ElementKind.ENUM.name(), ElementKind.INTERFACE.name(), RecordCompatibility.KIND_RECORD}; - if (Arrays.binarySearch(kinds, declaredElement.getKind().name()) >= 0) { - JsonType knownType = context.getContext().getKnownType(declaredElement); - if (knownType != null) { - jsonType = knownType; - } - else { - //type not known, not specified. Last chance: look for the type definition. - TypeDefinition typeDefinition = context.getContext().findTypeDefinition(declaredElement); - if (typeDefinition != null) { - jsonType = new JsonClassType(typeDefinition); + switch (declaredElement.getKind()) { + case ENUM, CLASS, INTERFACE, RECORD -> { + JsonType knownType = context.getContext().getKnownType(declaredElement); + if (knownType != null) { + jsonType = knownType; + } + else { + //type not known, not specified. Last chance: look for the type definition. + TypeDefinition typeDefinition = context.getContext().findTypeDefinition(declaredElement); + if (typeDefinition != null) { + jsonType = new JsonClassType(typeDefinition); + } } } } diff --git a/java-json-client/src/main/java/com/webcohesion/enunciate/modules/java_json_client/ClientClassnameForMethod.java b/java-json-client/src/main/java/com/webcohesion/enunciate/modules/java_json_client/ClientClassnameForMethod.java index 895a544e5..b210da7ff 100644 --- a/java-json-client/src/main/java/com/webcohesion/enunciate/modules/java_json_client/ClientClassnameForMethod.java +++ b/java-json-client/src/main/java/com/webcohesion/enunciate/modules/java_json_client/ClientClassnameForMethod.java @@ -18,8 +18,8 @@ import com.webcohesion.enunciate.api.datatype.DataTypeReference; import com.webcohesion.enunciate.api.resources.Entity; import com.webcohesion.enunciate.api.resources.MediaTypeDescriptor; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.ClientName; import com.webcohesion.enunciate.metadata.qname.XmlQNameEnumRef; @@ -95,7 +95,7 @@ public String convert(TypeElement declaration) throws TemplateModelException { if (adaptingType != null) { return convert(adaptingType); } - if (RecordCompatibility.isClassOrRecord(declaration)) { + if (ElementUtils.isClassOrRecord(declaration)) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/java-xml-client/src/main/java/com/webcohesion/enunciate/modules/java_xml_client/ClientClassnameForMethod.java b/java-xml-client/src/main/java/com/webcohesion/enunciate/modules/java_xml_client/ClientClassnameForMethod.java index b5a94ca8d..08e853ced 100644 --- a/java-xml-client/src/main/java/com/webcohesion/enunciate/modules/java_xml_client/ClientClassnameForMethod.java +++ b/java-xml-client/src/main/java/com/webcohesion/enunciate/modules/java_xml_client/ClientClassnameForMethod.java @@ -18,8 +18,8 @@ import com.webcohesion.enunciate.api.datatype.DataTypeReference; import com.webcohesion.enunciate.api.resources.Entity; import com.webcohesion.enunciate.api.resources.MediaTypeDescriptor; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.ClientName; import com.webcohesion.enunciate.modules.jaxb.EnunciateJaxbContext; @@ -111,7 +111,7 @@ public String convert(TypeElement declaration) throws TemplateModelException { if (adapterType != null) { return convert(adapterType.getAdaptingType()); } - if (RecordCompatibility.isClassOrRecord(declaration)) { + if (ElementUtils.isClassOrRecord(declaration)) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/CompatElementFilter.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/CompatElementFilter.java deleted file mode 100644 index 3da4f6a01..000000000 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/CompatElementFilter.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.webcohesion.enunciate.javac; - -import javax.lang.model.element.Element; -import javax.lang.model.element.TypeElement; -import javax.lang.model.util.ElementFilter; -import java.util.ArrayList; -import java.util.List; - -/** - * Unified utility for handling java.lang.Record on JDK < 16. - */ -public final class CompatElementFilter { - private CompatElementFilter() { - } - - /** - * Get all fields in the class. If it is a java.lang.Record then get all the record components. - * - * @param clazz the class to - * @return a list of elements - */ - public static List fieldsOrRecordComponentsIn(TypeElement clazz) { - if (RecordCompatibility.isRecord(clazz)) { - List elements = new ArrayList<>(); - for (Element element : clazz.getEnclosedElements()) { - if (RecordCompatibility.isRecordComponent(element)) { - elements.add(element); - } - } - return elements; - } - else { - return new ArrayList<>(ElementFilter.fieldsIn(clazz.getEnclosedElements())); - } - } -} diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java deleted file mode 100644 index bdf03926c..000000000 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/RecordCompatibility.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.webcohesion.enunciate.javac; - -import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; - -/** - * Aids in adding record compatibility for JDK < 16. - */ -public final class RecordCompatibility { - public static final String KIND_RECORD = "RECORD"; - public static final String KIND_RECORD_COMPONENT = "RECORD_COMPONENT"; - public static final String CLASS_RECORD = "java.lang.Record"; - - private RecordCompatibility() { - } - - /** - * Check if the element is a record component. - * - * @param element the element to test - * @return true if it's a record component - */ - public static boolean isRecordComponent(Element element) { - return element != null && element.getKind().name().equals(KIND_RECORD_COMPONENT); - } - - /** - * Check if the element is a record. - * - * @param element the element to test - * @return true if it's a record - */ - public static boolean isRecord(Element element) { - return element.getKind().name().equals(KIND_RECORD); - } - - /** - * Check if the element is a class or record. - * - * @param element the element to test - * @return true if it's a class or record - */ - public static boolean isClassOrRecord(Element element) { - return element.getKind() == ElementKind.CLASS || isRecord(element); - } -} diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/DecoratedElements.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/DecoratedElements.java index dfd68e531..351e69951 100644 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/DecoratedElements.java +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/DecoratedElements.java @@ -15,7 +15,6 @@ */ package com.webcohesion.enunciate.javac.decorations; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.adaptors.ElementAdaptor; import com.webcohesion.enunciate.javac.decorations.adaptors.ExecutableElementAdaptor; import com.webcohesion.enunciate.javac.decorations.adaptors.TypeElementAdaptor; @@ -75,7 +74,7 @@ public String getDocComment(Element e) { } String recordComponentName = null; - if (RecordCompatibility.isRecordComponent(e)) { + if (e.getKind() == ElementKind.RECORD_COMPONENT) { recordComponentName = e.getSimpleName().toString(); e = e.getEnclosingElement(); } diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/DecoratedTypeElement.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/DecoratedTypeElement.java index 1e75c4251..83e6b83f3 100644 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/DecoratedTypeElement.java +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/DecoratedTypeElement.java @@ -15,7 +15,6 @@ */ package com.webcohesion.enunciate.javac.decorations.element; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; import com.webcohesion.enunciate.javac.decorations.ElementDecorator; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; @@ -152,7 +151,7 @@ public List enumValues() { public A getAnnotation(Class annotationType) { A annotation = super.getAnnotation(annotationType); - if (RecordCompatibility.isRecord(this) && annotation == null && (annotationType.getAnnotation(Inherited.class) != null) && (getSuperclass() instanceof DeclaredType)) { + if (ElementUtils.isClassOrRecord(this) && annotation == null && (annotationType.getAnnotation(Inherited.class) != null) && (getSuperclass() instanceof DeclaredType)) { TypeElement superDecl = (TypeElement) ((DeclaredType) getSuperclass()).asElement(); if ((superDecl != null) && (!Object.class.getName().equals(superDecl.getQualifiedName().toString()))) { return superDecl.getAnnotation(annotationType); @@ -165,7 +164,6 @@ public A getAnnotation(Class annotationType) { protected List loadProperties(PropertySpec spec) { HashMap getters = new HashMap(); HashMap setters = new HashMap(); - // TODO for (ExecutableElement method : getMethods()) { DecoratedExecutableElement decoratedMethod = (DecoratedExecutableElement) method; boolean getter = spec.isGetter(decoratedMethod); diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/ElementUtils.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/ElementUtils.java index 37043edca..85c5b4062 100644 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/ElementUtils.java +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/element/ElementUtils.java @@ -19,10 +19,14 @@ import com.webcohesion.enunciate.javac.javadoc.JavaDoc; import com.webcohesion.enunciate.javac.javadoc.JavaDocTagHandler; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -131,6 +135,37 @@ public static String capitalize(String string) { return Character.toUpperCase(string.charAt(0)) + string.substring(1); } + /** + * Check if the element is a class or record. + * + * @param element the element to test + * @return true if it's a class or record + */ + public static boolean isClassOrRecord(Element element) { + return element.getKind() == ElementKind.CLASS || element.getKind() == ElementKind.RECORD; + } + + /** + * Get all fields in the class. If it is a java.lang.Record then get all the record components. + * + * @param clazz the element to inspect + * @return a list of elements + */ + public static List fieldsOrRecordComponentsIn(TypeElement clazz) { + if (clazz.getKind() == ElementKind.RECORD) { + List elements = new ArrayList<>(); + for (Element element : clazz.getEnclosedElements()) { + if (element.getKind() == ElementKind.RECORD_COMPONENT) { + elements.add(element); + } + } + return elements; + } + else { + return new ArrayList<>(ElementFilter.fieldsIn(clazz.getEnclosedElements())); + } + } + public static class DefaultPropertySpec implements PropertySpec { protected final DecoratedProcessingEnvironment env; diff --git a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/type/DecoratedTypeMirror.java b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/type/DecoratedTypeMirror.java index 2faf34785..ae35dd092 100644 --- a/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/type/DecoratedTypeMirror.java +++ b/javac-support/src/main/java/com/webcohesion/enunciate/javac/decorations/type/DecoratedTypeMirror.java @@ -15,10 +15,10 @@ */ package com.webcohesion.enunciate.javac.decorations.type; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; import com.webcohesion.enunciate.javac.decorations.ElementDecorator; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecoration; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.javac.javadoc.DefaultJavaDocTagHandler; import com.webcohesion.enunciate.javac.javadoc.DocComment; import com.webcohesion.enunciate.javac.javadoc.JavaDocTagHandler; @@ -149,7 +149,7 @@ public boolean isClass() { private boolean isClassOrRecord() { Element element = ((DeclaredType) this.delegate).asElement(); - return RecordCompatibility.isClassOrRecord(element); + return ElementUtils.isClassOrRecord(element); } public boolean isDeclared() { diff --git a/javascript-client/src/main/java/com/webcohesion/enunciate/modules/javascript_client/ClientClassnameForMethod.java b/javascript-client/src/main/java/com/webcohesion/enunciate/modules/javascript_client/ClientClassnameForMethod.java index 73aa76ece..b46f1d145 100644 --- a/javascript-client/src/main/java/com/webcohesion/enunciate/modules/javascript_client/ClientClassnameForMethod.java +++ b/javascript-client/src/main/java/com/webcohesion/enunciate/modules/javascript_client/ClientClassnameForMethod.java @@ -19,7 +19,6 @@ import com.webcohesion.enunciate.api.datatype.DataTypeReference; import com.webcohesion.enunciate.api.resources.Entity; import com.webcohesion.enunciate.api.resources.MediaTypeDescriptor; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.ClientName; @@ -85,7 +84,7 @@ public ClientClassnameForMethod(Map conversions, EnunciateJackso classConversions.put(javax.xml.datatype.Duration.class.getName(), "String"); classConversions.put(jakarta.xml.bind.JAXBElement.class.getName(), "Object"); classConversions.put(Object.class.getName(), "Object"); - classConversions.put(RecordCompatibility.CLASS_RECORD, "Object"); + classConversions.put(Record.class.getName(), "Object"); } @Override diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java index befc22404..ac20d62aa 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/EnunciateJaxbContext.java @@ -18,8 +18,8 @@ import com.webcohesion.enunciate.CompletionFailureException; import com.webcohesion.enunciate.EnunciateContext; import com.webcohesion.enunciate.EnunciateException; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.javac.decorations.type.DecoratedDeclaredType; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.qname.XmlQNameEnum; @@ -192,7 +192,7 @@ protected Map loadKnownTypes() { knownTypes.put(java.net.URI.class.getName(), KnownXmlType.STRING); knownTypes.put(javax.xml.datatype.Duration.class.getName(), KnownXmlType.DURATION); knownTypes.put(java.lang.Object.class.getName(), KnownXmlType.ANY_TYPE); - knownTypes.put(RecordCompatibility.CLASS_RECORD, KnownXmlType.ANY_TYPE); + knownTypes.put(Record.class.getName(), KnownXmlType.ANY_TYPE); knownTypes.put(java.io.Serializable.class.getName(), KnownXmlType.ANY_TYPE); knownTypes.put(byte[].class.getName(), KnownXmlType.BASE64_BINARY); knownTypes.put(java.nio.ByteBuffer.class.getName(), KnownXmlType.BASE64_BINARY); @@ -474,7 +474,7 @@ protected void add(LocalElementDeclaration led, LinkedList stack) { protected void addReferencedTypeDefinitions(LocalElementDeclaration led, LinkedList stack) { addSeeAlsoTypeDefinitions(led, stack); DecoratedTypeElement scope = led.getElementScope(); - if (scope != null && (RecordCompatibility.isClassOrRecord(scope)) && !isKnownTypeDefinition(scope)) { + if (scope != null && ElementUtils.isClassOrRecord(scope) && !isKnownTypeDefinition(scope)) { add(createTypeDefinition(scope), stack); } TypeElement typeElement = null; @@ -486,7 +486,7 @@ protected void addReferencedTypeDefinitions(LocalElementDeclaration led, LinkedL } } - if (scope != null && (RecordCompatibility.isClassOrRecord(scope)) && !isKnownTypeDefinition(typeElement)) { + if (scope != null && ElementUtils.isClassOrRecord(scope) && !isKnownTypeDefinition(typeElement)) { add(createTypeDefinition(typeElement), stack); } } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/JaxbModule.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/JaxbModule.java index 0a6f74090..f9057f63e 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/JaxbModule.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/JaxbModule.java @@ -18,7 +18,6 @@ import com.webcohesion.enunciate.CompletionFailureException; import com.webcohesion.enunciate.EnunciateContext; import com.webcohesion.enunciate.api.ApiRegistry; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.metadata.Ignore; import com.webcohesion.enunciate.module.*; @@ -161,7 +160,7 @@ else if (!this.jaxbContext.isKnownTypeDefinition((TypeElement) declaration) && i } protected boolean isExplicitTypeDefinition(Element declaration) { - if (declaration.getKind() != ElementKind.CLASS && declaration.getKind() != ElementKind.ENUM && !RecordCompatibility.isRecord(declaration)) { + if (declaration.getKind() != ElementKind.CLASS && declaration.getKind() != ElementKind.ENUM && !(declaration.getKind() == ElementKind.RECORD)) { debug("%s isn't a potential JAXB type because it's not a class or an enum.", declaration); return false; } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java index e01652207..2bf5dc676 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/Accessor.java @@ -21,6 +21,7 @@ import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; import com.webcohesion.enunciate.javac.decorations.element.DecoratedElement; import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.javac.decorations.element.PropertyElement; import com.webcohesion.enunciate.javac.decorations.type.DecoratedDeclaredType; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; @@ -35,7 +36,6 @@ import com.webcohesion.enunciate.modules.jaxb.model.types.XmlTypeFactory; import com.webcohesion.enunciate.modules.jaxb.model.util.JAXBUtil; import com.webcohesion.enunciate.modules.jaxb.model.util.MapType; -import com.webcohesion.enunciate.javac.CompatElementFilter; import com.webcohesion.enunciate.util.HasClientConvertibleType; import com.webcohesion.enunciate.util.OptionalUtils; @@ -378,7 +378,7 @@ private DecoratedElement getXmlIDAccessor(DecoratedDeclaredType classType) { return null; } - for (Element field : CompatElementFilter.fieldsOrRecordComponentsIn(declaration)) { + for (Element field : ElementUtils.fieldsOrRecordComponentsIn(declaration)) { if (field.getAnnotation(XmlID.class) != null) { return (DecoratedElement) field; } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/ComplexTypeDefinition.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/ComplexTypeDefinition.java index ccc352921..1770dd94a 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/ComplexTypeDefinition.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/ComplexTypeDefinition.java @@ -15,7 +15,6 @@ */ package com.webcohesion.enunciate.modules.jaxb.model; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.modules.jaxb.EnunciateJaxbContext; import com.webcohesion.enunciate.modules.jaxb.model.types.KnownXmlType; import com.webcohesion.enunciate.modules.jaxb.model.types.XmlType; @@ -115,7 +114,7 @@ public boolean isBaseObject() { TypeElement superDeclaration = (TypeElement) this.env.getTypeUtils().asElement(superclass); return superDeclaration == null || Object.class.getName().equals(superDeclaration.getQualifiedName().toString()) - || RecordCompatibility.CLASS_RECORD.equals(superDeclaration.getQualifiedName().toString()) + || Record.class.getName().equals(superDeclaration.getQualifiedName().toString()) || isXmlTransient(superDeclaration); } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java index ee25d8605..b11c28c14 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/TypeDefinition.java @@ -23,6 +23,7 @@ import com.webcohesion.enunciate.javac.decorations.element.DecoratedElement; import com.webcohesion.enunciate.javac.decorations.element.DecoratedExecutableElement; import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.javac.decorations.element.PropertyElement; import com.webcohesion.enunciate.metadata.ClientName; import com.webcohesion.enunciate.metadata.qname.XmlQNameEnumRef; @@ -37,7 +38,6 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; -import com.webcohesion.enunciate.javac.CompatElementFilter; import jakarta.xml.bind.annotation.*; import javax.xml.namespace.QName; import java.beans.Introspector; @@ -200,7 +200,7 @@ protected void aggregatePotentialAccessors(AccessorBag bag, DecoratedTypeElement aggregatePotentialAccessors(bag, superDeclaration, filter, true); } - for (javax.lang.model.element.Element fieldDeclaration : CompatElementFilter.fieldsOrRecordComponentsIn(clazz)) { + for (javax.lang.model.element.Element fieldDeclaration : ElementUtils.fieldsOrRecordComponentsIn(clazz)) { if (!filter.accept((DecoratedElement) fieldDeclaration)) { bag.fields.removeByName(fieldDeclaration); } diff --git a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/types/XmlTypeVisitor.java b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/types/XmlTypeVisitor.java index 8e9684163..b4832045f 100644 --- a/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/types/XmlTypeVisitor.java +++ b/jaxb/src/main/java/com/webcohesion/enunciate/modules/jaxb/model/types/XmlTypeVisitor.java @@ -16,7 +16,6 @@ package com.webcohesion.enunciate.modules.jaxb.model.types; import com.webcohesion.enunciate.EnunciateException; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.modules.jaxb.EnunciateJaxbContext; import com.webcohesion.enunciate.modules.jaxb.model.TypeDefinition; import com.webcohesion.enunciate.modules.jaxb.model.adapters.AdapterType; @@ -24,11 +23,9 @@ import com.webcohesion.enunciate.modules.jaxb.model.util.MapType; import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.lang.model.type.*; import javax.lang.model.util.SimpleTypeVisitor6; -import java.util.Arrays; import java.util.LinkedList; /** @@ -76,17 +73,18 @@ public XmlType visitDeclared(DeclaredType declaredType, Context context) { return new MapXmlType(keyType, valueType); } else { - String[] kinds = {ElementKind.CLASS.name(), ElementKind.ENUM.name(), RecordCompatibility.KIND_RECORD}; - if(Arrays.binarySearch(kinds,declaredElement.getKind().name()) >=0) { - XmlType knownType = context.getContext().getKnownType(declaredElement); - if (knownType != null) { - return knownType; - } - else { - //type not known, not specified. Last chance: look for the type definition. - TypeDefinition typeDefinition = context.getContext().findTypeDefinition(declaredElement); - if (typeDefinition != null) { - return new XmlClassType(typeDefinition); + switch (declaredElement.getKind()) { + case CLASS, ENUM, RECORD -> { + XmlType knownType = context.getContext().getKnownType(declaredElement); + if (knownType != null) { + return knownType; + } + else { + //type not known, not specified. Last chance: look for the type definition. + TypeDefinition typeDefinition = context.getContext().findTypeDefinition(declaredElement); + if (typeDefinition != null) { + return new XmlClassType(typeDefinition); + } } } } diff --git a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java index d6b74c8af..fa4bc4857 100644 --- a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java +++ b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/Resource.java @@ -17,15 +17,14 @@ import com.webcohesion.enunciate.facets.Facet; import com.webcohesion.enunciate.facets.HasFacets; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.javac.decorations.element.PropertyElement; import com.webcohesion.enunciate.javac.decorations.type.TypeVariableContext; import com.webcohesion.enunciate.modules.jaxrs.EnunciateJaxrsContext; import com.webcohesion.enunciate.modules.jaxrs.model.util.JaxrsUtil; import com.webcohesion.enunciate.util.AnnotationUtils; -import com.webcohesion.enunciate.javac.CompatElementFilter; import jakarta.annotation.security.RolesAllowed; import javax.lang.model.element.*; import javax.lang.model.type.DeclaredType; @@ -122,7 +121,7 @@ protected List getSubresourceLocators(TypeElement delegate, } - if (RecordCompatibility.isClassOrRecord(delegate)) { + if (ElementUtils.isClassOrRecord(delegate)) { TypeMirror superclass = delegate.getSuperclass(); if (superclass instanceof DeclaredType && ((DeclaredType)superclass).asElement() != null) { List superMethods = getSubresourceLocators((TypeElement) ((DeclaredType) superclass).asElement(), variableContext, context); @@ -182,7 +181,7 @@ protected List getResourceMethods(final TypeElement delegate, Ty } } - if (RecordCompatibility.isRecordComponent(delegate)) { + if (ElementUtils.isClassOrRecord(delegate)) { TypeMirror superclass = delegate.getSuperclass(); if (superclass instanceof DeclaredType && ((DeclaredType)superclass).asElement() != null) { DeclaredType declared = (DeclaredType) superclass; @@ -212,7 +211,7 @@ protected Set getResourceParameters(TypeElement delegate, Enu } Set resourceParameters = new TreeSet(); - for (Element field : CompatElementFilter.fieldsOrRecordComponentsIn(delegate)) { + for (Element field : ElementUtils.fieldsOrRecordComponentsIn(delegate)) { if (ResourceParameter.isResourceParameter(field, this.context)) { resourceParameters.add(new ResourceParameter(field, this)); } @@ -224,7 +223,7 @@ protected Set getResourceParameters(TypeElement delegate, Enu } } - if (RecordCompatibility.isClassOrRecord(delegate) && delegate.getSuperclass() instanceof DeclaredType) { + if (ElementUtils.isClassOrRecord(delegate) && delegate.getSuperclass() instanceof DeclaredType) { Set superParams = getResourceParameters((TypeElement) ((DeclaredType) delegate.getSuperclass()).asElement(), context); for (ResourceParameter superParam : superParams) { if (!isHidden(superParam, resourceParameters)) { diff --git a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java index 69d9ebfe9..63a5a39c9 100644 --- a/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java +++ b/jaxrs/src/main/java/com/webcohesion/enunciate/modules/jaxrs/model/ResourceParameter.java @@ -15,7 +15,6 @@ */ package com.webcohesion.enunciate.modules.jaxrs.model; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; import com.webcohesion.enunciate.javac.decorations.ElementDecorator; import com.webcohesion.enunciate.javac.decorations.element.*; @@ -26,7 +25,6 @@ import com.webcohesion.enunciate.metadata.rs.TypeHint; import com.webcohesion.enunciate.modules.jaxrs.EnunciateJaxrsContext; import com.webcohesion.enunciate.util.AnnotationUtils; -import com.webcohesion.enunciate.javac.CompatElementFilter; import com.webcohesion.enunciate.util.TypeHintUtils; import jakarta.annotation.Nullable; @@ -247,7 +245,7 @@ public static List getFormBeanParameters(VariableElement para private static void gatherFormBeanParameters(TypeMirror type, ArrayList beanParams, PathContext context) { if (type instanceof DeclaredType) { DecoratedTypeElement typeDeclaration = (DecoratedTypeElement) ElementDecorator.decorate(((DeclaredType) type).asElement(), context.getContext().getContext().getProcessingEnvironment()); - for (Element field : CompatElementFilter.fieldsOrRecordComponentsIn(typeDeclaration)) { + for (Element field : ElementUtils.fieldsOrRecordComponentsIn(typeDeclaration)) { if (isResourceParameter(field, context.getContext())) { beanParams.add(new ResourceParameter(field, context)); } @@ -266,7 +264,7 @@ else if (isBeanParameter(property)) { } } - if (RecordCompatibility.isClassOrRecord(typeDeclaration)) { + if (ElementUtils.isClassOrRecord(typeDeclaration)) { gatherFormBeanParameters(typeDeclaration.getSuperclass(), beanParams, context); } } diff --git a/jaxws/src/main/java/com/webcohesion/enunciate/modules/jaxws/model/EndpointInterface.java b/jaxws/src/main/java/com/webcohesion/enunciate/modules/jaxws/model/EndpointInterface.java index 4b5cc9495..5fca584a7 100644 --- a/jaxws/src/main/java/com/webcohesion/enunciate/modules/jaxws/model/EndpointInterface.java +++ b/jaxws/src/main/java/com/webcohesion/enunciate/modules/jaxws/model/EndpointInterface.java @@ -18,9 +18,9 @@ import com.webcohesion.enunciate.EnunciateException; import com.webcohesion.enunciate.facets.Facet; import com.webcohesion.enunciate.facets.HasFacets; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.TypeElementComparator; import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.javac.decorations.type.TypeVariableContext; import com.webcohesion.enunciate.metadata.ClientName; import com.webcohesion.enunciate.metadata.soap.SoapBindingName; @@ -77,7 +77,7 @@ public EndpointInterface(TypeElement delegate, Set implementa annotation = getAnnotation(jakarta.jws.WebService.class); impls = new ArrayList(); if (annotation != null) { - if (RecordCompatibility.isClassOrRecord(this)) { + if (ElementUtils.isClassOrRecord(this)) { //if the declaration is a class, the endpoint interface is implied... impls.add(new EndpointImplementation(getDelegate(), this, context)); } @@ -106,7 +106,7 @@ public EndpointInterface(TypeElement delegate, Set implementa } } - if (RecordCompatibility.isClassOrRecord(delegate)) { + if (ElementUtils.isClassOrRecord(delegate)) { //the spec says we need to consider superclass methods, too... TypeMirror superclass = delegate.getSuperclass(); if (superclass instanceof DeclaredType) { @@ -311,7 +311,7 @@ public Collection getEndpointImplementations() { * A quick check to see if a declaration is an endpoint implementation. */ protected boolean isEndpointImplementation(TypeElement declaration) { - if (RecordCompatibility.isClassOrRecord(declaration) && !declaration.getQualifiedName().equals(getQualifiedName())) { + if (ElementUtils.isClassOrRecord(declaration) && !declaration.getQualifiedName().equals(getQualifiedName())) { WebService webServiceInfo = declaration.getAnnotation(WebService.class); return webServiceInfo != null && getQualifiedName().toString().equals(webServiceInfo.endpointInterface()); } diff --git a/obj-c-xml-client/src/main/java/com/webcohesion/enunciate/modules/objc_client/ClientClassnameForMethod.java b/obj-c-xml-client/src/main/java/com/webcohesion/enunciate/modules/objc_client/ClientClassnameForMethod.java index b0d29f0fc..fa19f5f7a 100644 --- a/obj-c-xml-client/src/main/java/com/webcohesion/enunciate/modules/objc_client/ClientClassnameForMethod.java +++ b/obj-c-xml-client/src/main/java/com/webcohesion/enunciate/modules/objc_client/ClientClassnameForMethod.java @@ -15,8 +15,8 @@ */ package com.webcohesion.enunciate.modules.objc_client; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.metadata.ClientName; import com.webcohesion.enunciate.modules.jaxb.EnunciateJaxbContext; import com.webcohesion.enunciate.modules.jaxb.model.Accessor; @@ -28,7 +28,7 @@ import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import jakarta.activation.DataHandler; -import javax.lang.model.element.ElementKind; + import javax.lang.model.element.TypeElement; import javax.lang.model.type.*; import jakarta.xml.bind.JAXBElement; @@ -96,7 +96,7 @@ else if (isCollection(declaration)) { if (adapterType != null) { return convert(adapterType.getAdaptingType()); } - if (RecordCompatibility.isClassOrRecord(declaration)) { + if (ElementUtils.isClassOrRecord(declaration)) { DecoratedTypeMirror superType = (DecoratedTypeMirror) TypeMirrorDecorator.decorate(declaration.getSuperclass(), this.context.getProcessingEnvironment()); if (superType != null && superType.isInstanceOf(JAXBElement.class.getName())) { //for client conversions, we're going to generalize subclasses of JAXBElement to JAXBElement diff --git a/pom.xml b/pom.xml index 518f16ead..464fea744 100644 --- a/pom.xml +++ b/pom.xml @@ -132,7 +132,6 @@ 3.3.0 3.3.0 1.6.0 - 3.3.2 https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HXSXBXUT63RCG diff --git a/rt-util/pom.xml b/rt-util/pom.xml index c2a7a41a8..093d4a3c9 100644 --- a/rt-util/pom.xml +++ b/rt-util/pom.xml @@ -59,7 +59,6 @@ org.mockito mockito-core - 5.6.0 test diff --git a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java index f70bf3d99..7e063cd86 100644 --- a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java +++ b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/RequestParameterFactory.java @@ -15,17 +15,16 @@ */ package com.webcohesion.enunciate.modules.spring_web.model; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.DecoratedProcessingEnvironment; import com.webcohesion.enunciate.javac.decorations.ElementDecorator; import com.webcohesion.enunciate.javac.decorations.TypeMirrorDecorator; import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; import com.webcohesion.enunciate.javac.decorations.element.DecoratedVariableElement; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.javac.decorations.element.PropertyElement; import com.webcohesion.enunciate.javac.decorations.type.DecoratedTypeMirror; import com.webcohesion.enunciate.javac.decorations.type.TypeVariableContext; import com.webcohesion.enunciate.util.AnnotationUtils; -import com.webcohesion.enunciate.javac.CompatElementFilter; import org.springframework.web.bind.annotation.*; import javax.lang.model.element.*; @@ -184,7 +183,7 @@ private static void gatherFormObjectParameters(TypeMirror type, ArrayList methods = context.getHttpMethods(); ResourceParameterType defaultType = methods.contains("POST") ? ResourceParameterType.FORM : ResourceParameterType.QUERY; DecoratedTypeElement typeDeclaration = (DecoratedTypeElement) ElementDecorator.decorate(((DeclaredType) type).asElement(), context.getContext().getContext().getProcessingEnvironment()); - for (Element field : CompatElementFilter.fieldsOrRecordComponentsIn(typeDeclaration)) { + for (Element field : ElementUtils.fieldsOrRecordComponentsIn(typeDeclaration)) { DecoratedVariableElement decorated = (DecoratedVariableElement) field; if (!decorated.isFinal() && !decorated.isTransient() && decorated.isPublic()) { params.add(new SimpleRequestParameter(decorated, context, defaultType)); @@ -197,7 +196,7 @@ private static void gatherFormObjectParameters(TypeMirror type, ArrayList getRequestMappings(final TypeElement delegate, Ty } } - if (RecordCompatibility.isClassOrRecord(delegate)) { + if (ElementUtils.isClassOrRecord(delegate)) { TypeMirror superclass = delegate.getSuperclass(); if (superclass instanceof DeclaredType && ((DeclaredType) superclass).asElement() != null) { DeclaredType declared = (DeclaredType) superclass; diff --git a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/SpringControllerAdvice.java b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/SpringControllerAdvice.java index 8cd8195b4..8778ad550 100644 --- a/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/SpringControllerAdvice.java +++ b/spring-web/src/main/java/com/webcohesion/enunciate/modules/spring_web/model/SpringControllerAdvice.java @@ -15,8 +15,8 @@ */ package com.webcohesion.enunciate.modules.spring_web.model; -import com.webcohesion.enunciate.javac.RecordCompatibility; import com.webcohesion.enunciate.javac.decorations.element.DecoratedTypeElement; +import com.webcohesion.enunciate.javac.decorations.element.ElementUtils; import com.webcohesion.enunciate.javac.decorations.type.TypeVariableContext; import com.webcohesion.enunciate.modules.spring_web.EnunciateSpringWebContext; import org.springframework.web.bind.annotation.ControllerAdvice; @@ -188,7 +188,7 @@ protected List findRequestMappingAdvice(RequestMapping req } } - if (RecordCompatibility.isClassOrRecord(controllerAdvice)) { + if (ElementUtils.isClassOrRecord(controllerAdvice)) { TypeMirror superclass = controllerAdvice.getSuperclass(); if (superclass instanceof DeclaredType && ((DeclaredType)superclass).asElement() != null) { DeclaredType declared = (DeclaredType) superclass;