├── .github
└── workflows
│ ├── build.yaml
│ ├── compatibility.yaml
│ ├── docs.yaml
│ └── release.yaml
├── .gitignore
├── .mvn
├── jvm.config
└── wrapper
│ └── maven-wrapper.properties
├── CODE_OF_CONDUCT.adoc
├── LICENSE
├── README.adoc
├── application.yml
├── etc
├── backport-ticket.sh
├── ide
│ ├── eclipse-formatting.xml
│ └── intellij-formatting.jar
├── mappings.txt
├── migrate-to-1.0.sh
├── release.adoc
└── update-dependencies.sh
├── lombok.config
├── mvnw
├── mvnw.cmd
├── pom.xml
├── settings.xml
└── src
├── docs
├── java
│ └── org
│ │ └── springframework
│ │ └── hateoas
│ │ ├── AffordancesSample.java
│ │ ├── CollectionJsonApplication.java
│ │ ├── EmployeeController.java
│ │ ├── EmployeeModel.java
│ │ ├── ForwardedEnabledConfig.java
│ │ ├── FundamentalsTest.java
│ │ ├── HalFormsApplication.java
│ │ ├── PaymentProcessingApp.java
│ │ ├── PaymentProcessor.java
│ │ ├── SampleAppConfiguration.java
│ │ ├── UberApplication.java
│ │ ├── client
│ │ └── HypermediaConfiguration.java
│ │ ├── mediatype
│ │ └── problem
│ │ │ ├── PaymentController.java
│ │ │ ├── PaymentResult.java
│ │ │ └── PaymentService.java
│ │ └── support
│ │ ├── Customer.java
│ │ ├── Order.java
│ │ ├── Payment.java
│ │ └── PaymentController.java
└── resources
│ ├── assemblies
│ └── docs.xml
│ └── org
│ └── springframework
│ └── hateoas
│ └── docs
│ ├── mediatype
│ ├── collectionjson
│ │ ├── spec-part1.json
│ │ ├── spec-part2.json
│ │ ├── spec-part3.json
│ │ ├── spec-part4.json
│ │ ├── spec-part5.json
│ │ ├── spec-part6.json
│ │ └── spec-part7.json
│ ├── hal
│ │ ├── forms
│ │ │ ├── hal-forms-sample-with-notes.json
│ │ │ └── hal-forms-sample.json
│ │ ├── hal-multiple-entry-link-relation.json
│ │ ├── hal-single-entry-link-relation-array.json
│ │ ├── hal-single-entry-link-relation-object.json
│ │ └── hal-with-curies.json
│ ├── problem
│ │ └── response.json
│ └── uber
│ │ └── uber-sample.json
│ ├── order-plain.json
│ └── order-with-payment-link.json
├── main
├── asciidoc
│ ├── client.adoc
│ ├── configuration.adoc
│ ├── fundamentals.adoc
│ ├── index.adoc
│ ├── mediatypes.adoc
│ ├── migrate-to-1.0.adoc
│ └── server.adoc
├── java
│ └── org
│ │ └── springframework
│ │ └── hateoas
│ │ ├── Affordance.java
│ │ ├── AffordanceModel.java
│ │ ├── CollectionModel.java
│ │ ├── EntityModel.java
│ │ ├── IanaLinkRelations.java
│ │ ├── IanaUriSchemes.java
│ │ ├── InputType.java
│ │ ├── Link.java
│ │ ├── LinkParser.java
│ │ ├── LinkRelation.java
│ │ ├── Links.java
│ │ ├── MediaTypes.java
│ │ ├── NonComposite.java
│ │ ├── PagedModel.java
│ │ ├── QueryParameter.java
│ │ ├── RepresentationModel.java
│ │ ├── SlicedModel.java
│ │ ├── StringLinkRelation.java
│ │ ├── TemplateVariable.java
│ │ ├── TemplateVariables.java
│ │ ├── UriTemplate.java
│ │ ├── aot
│ │ ├── AotUtils.java
│ │ ├── ControllerMethodReturnTypeAotProcessor.java
│ │ ├── HateoasTypesRuntimeHints.java
│ │ ├── HypermediaTypeAotProcessor.java
│ │ ├── HypermediaTypesRuntimeHints.java
│ │ ├── RepresentationModelAssemblerAotProcessor.java
│ │ └── package-info.java
│ │ ├── client
│ │ ├── Hop.java
│ │ ├── JsonPathLinkDiscoverer.java
│ │ ├── LinkDiscoverer.java
│ │ ├── LinkDiscoverers.java
│ │ ├── Rels.java
│ │ ├── Traverson.java
│ │ ├── TraversonDefaults.java
│ │ └── package-info.java
│ │ ├── config
│ │ ├── EnableHypermediaSupport.java
│ │ ├── EntityLinksConfiguration.java
│ │ ├── HateoasConfiguration.java
│ │ ├── HypermediaConfigurationImportSelector.java
│ │ ├── HypermediaMappingInformation.java
│ │ ├── HypermediaMappingInformationComparator.java
│ │ ├── HypermediaRestTemplateConfigurer.java
│ │ ├── HypermediaWebClientConfigurer.java
│ │ ├── HypermediaWebTestClientConfigurer.java
│ │ ├── MediaTypeConfigurationProvider.java
│ │ ├── RestTemplateHateoasConfiguration.java
│ │ ├── WebClientHateoasConfiguration.java
│ │ ├── WebConverters.java
│ │ ├── WebFluxHateoasConfiguration.java
│ │ ├── WebMvcEntityLinksConfiguration.java
│ │ ├── WebMvcHateoasConfiguration.java
│ │ ├── WebStackImportSelector.java
│ │ ├── WebTestHateoasConfiguration.java
│ │ ├── WebfluxCodecCustomizer.java
│ │ └── package-info.java
│ │ ├── mediatype
│ │ ├── AffordanceModelFactory.java
│ │ ├── AffordanceOperations.java
│ │ ├── Affordances.java
│ │ ├── ConfigurableAffordance.java
│ │ ├── ConfigurableHandlerInstantiator.java
│ │ ├── ConfiguredAffordance.java
│ │ ├── DefaultOnlyMessageResolver.java
│ │ ├── InputTypeFactory.java
│ │ ├── JacksonHelper.java
│ │ ├── MediaTypeConfigurationCustomizer.java
│ │ ├── MediaTypeConfigurationFactory.java
│ │ ├── MessageResolver.java
│ │ ├── MessageSourceResolvableSerializer.java
│ │ ├── MessageSourceResolver.java
│ │ ├── PropertyUtils.java
│ │ ├── TypeBasedPayloadMetadata.java
│ │ ├── alps
│ │ │ ├── Alps.java
│ │ │ ├── AlpsLinkDiscoverer.java
│ │ │ ├── Descriptor.java
│ │ │ ├── Doc.java
│ │ │ ├── Ext.java
│ │ │ ├── Format.java
│ │ │ ├── Type.java
│ │ │ └── package-info.java
│ │ ├── collectionjson
│ │ │ ├── CollectionJson.java
│ │ │ ├── CollectionJsonAffordanceModel.java
│ │ │ ├── CollectionJsonAffordanceModelFactory.java
│ │ │ ├── CollectionJsonData.java
│ │ │ ├── CollectionJsonDocument.java
│ │ │ ├── CollectionJsonError.java
│ │ │ ├── CollectionJsonItem.java
│ │ │ ├── CollectionJsonLinkDiscoverer.java
│ │ │ ├── CollectionJsonMediaTypeConfiguration.java
│ │ │ ├── CollectionJsonMediaTypeConfigurationProvider.java
│ │ │ ├── CollectionJsonQuery.java
│ │ │ ├── CollectionJsonTemplate.java
│ │ │ ├── CollectionRepresentationModelMixin.java
│ │ │ ├── EntityRepresentationModelMixin.java
│ │ │ ├── Jackson2CollectionJsonModule.java
│ │ │ ├── PagedResourcesMixin.java
│ │ │ ├── RepresentationModelMixin.java
│ │ │ └── package-info.java
│ │ ├── hal
│ │ │ ├── CollectionModelMixin.java
│ │ │ ├── CurieProvider.java
│ │ │ ├── DefaultCurieProvider.java
│ │ │ ├── HalConfiguration.java
│ │ │ ├── HalEmbeddedBuilder.java
│ │ │ ├── HalLinkDiscoverer.java
│ │ │ ├── HalLinkRelation.java
│ │ │ ├── HalMediaTypeConfiguration.java
│ │ │ ├── HalMediaTypeConfigurationProvider.java
│ │ │ ├── HalModelBuilder.java
│ │ │ ├── HalTraversonDefaults.java
│ │ │ ├── Jackson2HalModule.java
│ │ │ ├── LinkMixin.java
│ │ │ ├── RepresentationModelMixin.java
│ │ │ ├── forms
│ │ │ │ ├── HalFormsAffordanceModel.java
│ │ │ │ ├── HalFormsAffordanceModelFactory.java
│ │ │ │ ├── HalFormsConfiguration.java
│ │ │ │ ├── HalFormsDeserializers.java
│ │ │ │ ├── HalFormsHttpMessageConverter.java
│ │ │ │ ├── HalFormsLinkDiscoverer.java
│ │ │ │ ├── HalFormsMediaTypeConfiguration.java
│ │ │ │ ├── HalFormsMediaTypeConfigurationProvider.java
│ │ │ │ ├── HalFormsOptions.java
│ │ │ │ ├── HalFormsOptionsFactory.java
│ │ │ │ ├── HalFormsPromptedValue.java
│ │ │ │ ├── HalFormsProperty.java
│ │ │ │ ├── HalFormsPropertyFactory.java
│ │ │ │ ├── HalFormsTemplate.java
│ │ │ │ ├── HalFormsTemplateBuilder.java
│ │ │ │ ├── HalFormsTemplatePropertyWriter.java
│ │ │ │ ├── Jackson2HalFormsModule.java
│ │ │ │ └── package-info.java
│ │ │ └── package-info.java
│ │ ├── html
│ │ │ ├── HtmlInputType.java
│ │ │ ├── HtmlInputTypeFactory.java
│ │ │ └── package-info.java
│ │ ├── package-info.java
│ │ ├── problem
│ │ │ ├── HttpProblemDetailsConfigurationProvider.java
│ │ │ ├── HttpProblemDetailsMappingInformation.java
│ │ │ ├── Problem.java
│ │ │ └── package-info.java
│ │ └── uber
│ │ │ ├── Jackson2UberModule.java
│ │ │ ├── Uber.java
│ │ │ ├── UberAction.java
│ │ │ ├── UberAffordanceModel.java
│ │ │ ├── UberAffordanceModelFactory.java
│ │ │ ├── UberData.java
│ │ │ ├── UberDocument.java
│ │ │ ├── UberError.java
│ │ │ ├── UberLinkDiscoverer.java
│ │ │ ├── UberMediaTypeConfiguration.java
│ │ │ ├── UberMediaTypeConfigurationProvider.java
│ │ │ └── package-info.java
│ │ ├── package-info.java
│ │ ├── server
│ │ ├── EntityLinks.java
│ │ ├── ExposesResourceFor.java
│ │ ├── LinkBuilder.java
│ │ ├── LinkBuilderFactory.java
│ │ ├── LinkRelationProvider.java
│ │ ├── MethodLinkBuilderFactory.java
│ │ ├── RepresentationModelAssembler.java
│ │ ├── RepresentationModelProcessor.java
│ │ ├── SimpleRepresentationModelAssembler.java
│ │ ├── TypedEntityLinks.java
│ │ ├── core
│ │ │ ├── AbstractEntityLinks.java
│ │ │ ├── AnnotationAttribute.java
│ │ │ ├── AnnotationLinkRelationProvider.java
│ │ │ ├── AnnotationMappingDiscoverer.java
│ │ │ ├── CachingMappingDiscoverer.java
│ │ │ ├── ControllerEntityLinks.java
│ │ │ ├── ControllerEntityLinksFactoryBean.java
│ │ │ ├── DefaultLinkRelationProvider.java
│ │ │ ├── DefaultMethodInvocation.java
│ │ │ ├── DelegatingEntityLinks.java
│ │ │ ├── DelegatingLinkRelationProvider.java
│ │ │ ├── DummyInvocationUtils.java
│ │ │ ├── EmbeddedWrapper.java
│ │ │ ├── EmbeddedWrappers.java
│ │ │ ├── EncodingUtils.java
│ │ │ ├── EvoInflectorLinkRelationProvider.java
│ │ │ ├── HeaderLinksResponseEntity.java
│ │ │ ├── LastInvocationAware.java
│ │ │ ├── LinkBuilderSupport.java
│ │ │ ├── MappingDiscoverer.java
│ │ │ ├── MethodInvocation.java
│ │ │ ├── MethodParameters.java
│ │ │ ├── PropertyResolvingMappingDiscoverer.java
│ │ │ ├── RawMappingDiscoverer.java
│ │ │ ├── Relation.java
│ │ │ ├── SpringAffordanceBuilder.java
│ │ │ ├── TemplateVariableAwareLinkBuilderSupport.java
│ │ │ ├── TypeReferences.java
│ │ │ ├── UriMapping.java
│ │ │ ├── UriTemplateFactory.java
│ │ │ ├── WebHandler.java
│ │ │ └── package-info.java
│ │ ├── mvc
│ │ │ ├── BasicLinkBuilder.java
│ │ │ ├── ControllerLinkRelationProvider.java
│ │ │ ├── JacksonSerializers.java
│ │ │ ├── MvcLink.java
│ │ │ ├── RepresentationModelAssemblerSupport.java
│ │ │ ├── RepresentationModelProcessorHandlerMethodReturnValueHandler.java
│ │ │ ├── RepresentationModelProcessorInvoker.java
│ │ │ ├── TypeConstrainedMappingJackson2HttpMessageConverter.java
│ │ │ ├── UriComponentsBuilderFactory.java
│ │ │ ├── UriComponentsContributor.java
│ │ │ ├── WebMvcLinkBuilder.java
│ │ │ ├── WebMvcLinkBuilderFactory.java
│ │ │ └── package-info.java
│ │ ├── package-info.java
│ │ └── reactive
│ │ │ ├── ReactiveRepresentationModelAssembler.java
│ │ │ ├── SimpleReactiveRepresentationModelAssembler.java
│ │ │ ├── WebFluxLinkBuilder.java
│ │ │ └── package-info.java
│ │ └── support
│ │ ├── ClassUtils.java
│ │ ├── WebStack.java
│ │ └── package-info.java
├── javadoc
│ ├── doc-files
│ │ └── th-background.png
│ └── spring-javadoc.css
├── kotlin
│ └── org
│ │ └── springframework
│ │ └── hateoas
│ │ └── server
│ │ ├── mvc
│ │ ├── WebMvcAffordanceBuilderDsl.kt
│ │ └── WebMvcLinkBuilderDsl.kt
│ │ └── reactive
│ │ ├── ReactiveRepresentationModelAssemblerBuildDsl.kt
│ │ └── SimpleReactiveRepresentationModelAssemblerBuildDsl.kt
└── resources
│ └── META-INF
│ ├── spring.factories
│ └── spring
│ └── aot.factories
└── test
├── java
└── org
│ └── springframework
│ └── hateoas
│ ├── AbstractJackson2MarshallingIntegrationTest.java
│ ├── ArchitectureTest.java
│ ├── CollectionModelUnitTest.java
│ ├── EntityModelIntegrationTest.java
│ ├── EntityModelUnitTest.java
│ ├── IanaLinkRelationUnitTest.java
│ ├── Jackson2LinkIntegrationTest.java
│ ├── Jackson2PagedResourcesIntegrationTest.java
│ ├── Jackson2ResourceIntegrationTest.java
│ ├── Jackson2ResourceSupportIntegrationTest.java
│ ├── LinkIntegrationTest.java
│ ├── LinkParserUnitTests.java
│ ├── LinkRelationUnitTest.java
│ ├── LinkUnitTest.java
│ ├── LinksUnitTest.java
│ ├── MappingTestUtils.java
│ ├── PagedModelUnitTest.java
│ ├── RepresentationModelIntegrationTest.java
│ ├── RepresentationModelUnitTest.java
│ ├── SimpleRepresentationModelAssemblerTest.java
│ ├── SlicedModelUnitTest.java
│ ├── StringLinkRelationUnitTest.java
│ ├── TemplateVariablesUnitTest.java
│ ├── TestUtils.java
│ ├── UriTemplateUnitTest.java
│ ├── aot
│ ├── AotUtilsUnitTests.java
│ ├── HateoasTypesRuntimeHintsUnitTests.java
│ └── HypermediaTypesRuntimeHintsUnitTests.java
│ ├── client
│ ├── Actor.java
│ ├── HopUnitTest.java
│ ├── Item.java
│ ├── LinkDiscovererUnitTest.java
│ ├── LinkDiscoverersUnitTest.java
│ ├── Movie.java
│ ├── Server.java
│ └── TraversonTest.java
│ ├── config
│ ├── CustomHypermediaWebFluxTest.java
│ ├── CustomHypermediaWebMvcTest.java
│ ├── EnableHypermediaSupportIntegrationTest.java
│ ├── HateoasConfigurationIntegrationTest.java
│ ├── HypermediaConfigurationImportSelectorUnitTest.java
│ ├── HypermediaRestTemplateBeanPostProcessorTest.java
│ ├── HypermediaRestTemplateConfigurerTest.java
│ ├── HypermediaWebClientBeanPostProcessorTest.java
│ ├── HypermediaWebClientConfigurerTest.java
│ ├── HypermediaWebFluxConfigurerTest.java
│ ├── HypermediaWebMvcConfigurerTest.java
│ ├── HypermediaWebTestClientConfigurerTest.java
│ ├── RestTemplateHateoasConfigurationIntegrationTest.java
│ ├── WebConvertersUnitTests.java
│ ├── WebStackImportSelectorUnitTest.java
│ └── XmlConfigurationIntegrationTest.java
│ ├── mediatype
│ ├── AffordancesUnitTests.java
│ ├── MediaTypeConfigurationFactoryUnitTests.java
│ ├── MediaTypeTestUtils.java
│ ├── PropertyUtilsTest.java
│ ├── alps
│ │ ├── AlpsLinkDiscoverUnitTest.java
│ │ ├── AlpsWebFluxIntegrationTest.java
│ │ ├── AlpsWebMvcIntegrationTest.java
│ │ └── JacksonSerializationTest.java
│ ├── collectionjson
│ │ ├── CollectionJsonLinkDiscovererUnitTest.java
│ │ ├── CollectionJsonSpecTest.java
│ │ ├── CollectionJsonWebFluxIntegrationTest.java
│ │ ├── CollectionJsonWebMvcIntegrationTest.java
│ │ ├── Jackson2CollectionJsonIntegrationTest.java
│ │ └── JacksonSerializationTest.java
│ ├── hal
│ │ ├── CustomizedHalLinkDiscovererUnitTest.java
│ │ ├── DefaultCurieProviderUnitTest.java
│ │ ├── HalConfigurationUnitTest.java
│ │ ├── HalEmbeddedBuilderUnitTest.java
│ │ ├── HalLinkDiscovererUnitTest.java
│ │ ├── HalLinkRelationUnitTest.java
│ │ ├── HalMediaTypeConfigurationIntegrationTest.java
│ │ ├── HalModelBuilderUnitTest.java
│ │ ├── HalObjectMapperCustomizerTest.java
│ │ ├── HalTestUtils.java
│ │ ├── Jackson2HalIntegrationTest.java
│ │ ├── RenderHypermediaForDefaultAcceptHeadersTest.java
│ │ ├── SimpleAnnotatedPojo.java
│ │ ├── SimplePojo.java
│ │ └── forms
│ │ │ ├── HalFormsLinkDiscovererUnitTest.java
│ │ │ ├── HalFormsMediaTypeConfigurationIntegrationTest.java
│ │ │ ├── HalFormsObjectMapperCustomizerTest.java
│ │ │ ├── HalFormsTemplateBuilderUnitTest.java
│ │ │ ├── HalFormsWebFluxIntegrationTest.java
│ │ │ ├── HalFormsWebMvcIntegrationTest.java
│ │ │ └── Jackson2HalFormsIntegrationTest.java
│ ├── html
│ │ └── HtmlInputTypeUnitTests.java
│ ├── problem
│ │ ├── HttpProblemDetailsIntegrationTest.java
│ │ └── JacksonSerializationTest.java
│ └── uber
│ │ ├── Jackson2UberIntegrationTest.java
│ │ ├── UberLinkDiscovererUnitTest.java
│ │ ├── UberWebFluxIntegrationTest.java
│ │ └── UberWebMvcIntegrationTest.java
│ ├── server
│ ├── core
│ │ ├── AnnotationLinkRelationProviderUnitTest.java
│ │ ├── AnnotationMappingDiscovererUnitTest.java
│ │ ├── ControllerEntityLinksFactoryBeanUnitTest.java
│ │ ├── ControllerEntityLinksUnitTest.java
│ │ ├── DelegatingEntityLinksUnitTest.java
│ │ ├── DelegatingRelProviderUnitTest.java
│ │ ├── EmbeddedWrappersUnitTest.java
│ │ ├── EvoInflectorRelProviderUnitTest.java
│ │ ├── JsonPathLinkDiscovererUnitTest.java
│ │ ├── LinkBuilderSupportUnitTest.java
│ │ ├── MethodParametersUnitTest.java
│ │ ├── PropertyResolvingMappingDiscovererUnitTest.java
│ │ └── TypeReferencesIntegrationTest.java
│ ├── mvc
│ │ ├── DummyInvocationUtilsUnitTest.java
│ │ ├── HeaderLinksResponseEntityUnitTest.java
│ │ ├── HttpEntityMatcher.java
│ │ ├── MultiMediaTypeWebMvcIntegrationTest.java
│ │ ├── MvcLinkUnitTests.java
│ │ ├── RepresentationModelProcessorIntegrationTest.java
│ │ ├── RepresentationModelProcessorInvokerUnitTests.java
│ │ ├── ResourceProcessorHandlerMethodReturnValueHandlerUnitTest.java
│ │ ├── TypeConstrainedMappingJackson2HttpMessageConverterUnitTest.java
│ │ ├── WebMvcLinkBuilderFactoryUnitTest.java
│ │ ├── WebMvcLinkBuilderOutsideSpringMvcUnitTest.java
│ │ └── WebMvcLinkBuilderUnitTest.java
│ └── reactive
│ │ ├── HypermediaWebFilterTest.java
│ │ ├── ReactiveResourceAssemblerUnitTest.java
│ │ ├── SimpleReactiveResourceAssemblerTest.java
│ │ └── WebFluxLinkBuilderTest.java
│ └── support
│ ├── ChangelogCreator.java
│ ├── ContextTester.java
│ ├── CustomHypermediaType.java
│ ├── Employee.java
│ ├── EmployeeResource.java
│ ├── HidingClassLoader.java
│ ├── JsonPathUtils.java
│ ├── MappingUtils.java
│ ├── WebFluxEmployeeController.java
│ └── WebMvcEmployeeController.java
├── kotlin
└── org
│ └── springframework
│ └── hateoas
│ └── server
│ ├── mvc
│ ├── WebMvcAffordanceBuilderDslUnitTest.kt
│ └── WebMvcLinkBuilderDslUnitTest.kt
│ └── reactive
│ ├── ReactiveRepresentationModelAssemblerBuilderDslUnitTest.kt
│ └── SimpleReactiveRepresentationModelAssemblerBuilderDslUnitTest.kt
└── resources
├── logback.xml
├── org
└── springframework
│ └── hateoas
│ ├── config
│ ├── application-context.xml
│ ├── rest-messages.properties
│ ├── webflux-frodo.json
│ └── webmvc-frodo.json
│ └── mediatype
│ ├── alps
│ ├── link-discoverer.json
│ └── reference.json
│ ├── collectionjson
│ ├── paged-resources.json
│ ├── reference.json
│ ├── resource-support-2.json
│ ├── resource-support-3.json
│ ├── resource-support.json
│ ├── resource.json
│ ├── resources-simple-pojos.json
│ ├── resources-with-resource-objects.json
│ ├── resources.json
│ ├── single-reactive-employee.json
│ ├── spec-part1.json
│ ├── spec-part2.json
│ ├── spec-part3.json
│ ├── spec-part4.json
│ ├── spec-part5.json
│ ├── spec-part6.json
│ ├── spec-part7-adjusted.json
│ └── spec-part7.json
│ ├── hal
│ ├── forms
│ │ ├── annotated-embedded-resources-reference.json
│ │ ├── annotated-paged-resources.json
│ │ ├── annotated-resource-resources.json
│ │ ├── curied-document.json
│ │ ├── employee-resource-support.json
│ │ ├── empty-document.json
│ │ ├── empty-embedded-pojos.json
│ │ ├── hal-forms-custom.json
│ │ ├── hal-forms-link-discoverer.json
│ │ ├── hal-forms-link.json
│ │ ├── link-template.json
│ │ ├── link-with-title.json
│ │ ├── list-link-reference.json
│ │ ├── multiple-curies-document.json
│ │ ├── multiple-resource-resources.json
│ │ ├── new-employee.json
│ │ ├── reference.json
│ │ ├── simple-embedded-resource-reference.json
│ │ ├── simple-resource-unwrapped.json
│ │ ├── single-embedded-resource-reference.json
│ │ ├── single-link-reference.json
│ │ └── single-non-curie-document.json
│ ├── hal-custom.json
│ ├── hal-embedded-author-illustrator.json
│ ├── hal-embedded-collection.json
│ ├── hal-empty.json
│ ├── hal-explicit-and-implicit-relations.json
│ ├── hal-link-discoverer.json
│ ├── hal-link.json
│ ├── hal-multiple-types.json
│ ├── hal-one-thing.json
│ ├── hal-single-item.json
│ ├── hal-two-things.json
│ └── zoom-hypermedia.json
│ ├── problem
│ ├── detail-only.json
│ ├── extension.json
│ ├── http-status-problem.json
│ ├── instance-only.json
│ ├── reference-1.json
│ ├── reference-2.json
│ ├── status-only.json
│ ├── title-only.json
│ └── type-only.json
│ ├── uber
│ ├── create-employee.json
│ ├── link-discovery.json
│ ├── paged-resources-empty-page.json
│ ├── paged-resources.json
│ ├── reference-links-only.json
│ ├── resource-support-2.json
│ ├── resource-support-pojo-empty.json
│ ├── resource-support-pojo.json
│ ├── resource-support.json
│ ├── resource-with-empty-pojo.json
│ ├── resource-with-simple-pojo.json
│ ├── resource-with-templated-link.json
│ ├── resource.json
│ ├── resource2.json
│ ├── resource3.json
│ ├── resource4.json
│ ├── resources-with-empty-resource-objects.json
│ ├── resources-with-resource-objects-and-empty-value.json
│ ├── resources-with-resource-objects.json
│ └── resources.json
│ └── vnderror
│ ├── vnderror-multiple-items.json
│ ├── vnderror-nested.json
│ ├── vnderror-single-item.json
│ └── vnderror-string-logref.json
├── pagedresources.xml
├── springagram-item-without-image.json
├── springagram-item.json
├── springagram-items.json
└── springagram-root.json
/.github/workflows/build.yaml:
--------------------------------------------------------------------------------
1 | name: CI Build
2 |
3 | on:
4 | push:
5 | branches: [ main, 3.0.x, 2.3.x, 2.2.x, 2.1.x, 2.0.x, 1.5.x ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 | jobs:
10 | build:
11 | name: Build project
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 |
16 | - name: Check out sources
17 | uses: actions/checkout@v4
18 |
19 | - name: Set up JDK 17
20 | uses: actions/setup-java@v4
21 | with:
22 | distribution: 'temurin'
23 | java-version: 17
24 | cache: 'maven'
25 |
26 | - name: Build with Maven
27 | run: ./mvnw -B
28 |
29 | - name: Deploy to Artifactory
30 | env:
31 | ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
32 | ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
33 | run: ./mvnw -B clean deploy -Pci,artifactory
34 |
--------------------------------------------------------------------------------
/.github/workflows/compatibility.yaml:
--------------------------------------------------------------------------------
1 | name: Compatibility builds
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: '5 6 * * *'
7 |
8 | jobs:
9 | compatibility:
10 |
11 | runs-on: ubuntu-latest
12 |
13 | strategy:
14 | matrix:
15 | branch: ['main', '2.3.x', '2.2.x', '2.1.x']
16 | spring: ['', 'spring-next', 'spring-61-next']
17 | kotlin: ['', 'kotlin-next', 'kotlin-2-next']
18 | jackson: ['', 'jackson-next']
19 |
20 | name: ${{ matrix.branch }} - ${{ matrix.spring }} ${{ matrix.kotlin }} ${{ matrix.jackson }}
21 |
22 | steps:
23 |
24 | - name: Check out sources
25 | uses: actions/checkout@v4
26 | with:
27 | ref: ${{ matrix.branch }}
28 |
29 | - name: Set up JDK 17
30 | uses: actions/setup-java@v4
31 | with:
32 | distribution: 'temurin'
33 | java-version: 17
34 | cache: 'maven'
35 |
36 | - name: List dependencies
37 | run: ./mvnw -D depedency:list -Dsort
38 | - name: Build
39 | run: ./mvnw -B verify -P${{ matrix.spring }},${{ matrix.kotlin }},${{ matrix.jackson }} --file pom.xml
40 |
--------------------------------------------------------------------------------
/.github/workflows/docs.yaml:
--------------------------------------------------------------------------------
1 | name: Publish Documentation
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | - cron: '0 0 * * *'
7 |
8 |
9 | jobs:
10 | build:
11 | name: Publish documentation
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 |
16 | - name: Check out sources
17 | uses: actions/checkout@v4
18 |
19 | - name: Set up JDK 17
20 | uses: actions/setup-java@v4
21 | with:
22 | distribution: 'temurin'
23 | java-version: 17
24 | cache: 'maven'
25 |
26 | - name: Setup Graphviz
27 | uses: ts-graphviz/setup-graphviz@v2
28 |
29 | - name: Deploy documentation
30 | env:
31 | ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
32 | ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
33 | run: ./mvnw -B clean deploy -Pdocumentation
34 |
--------------------------------------------------------------------------------
/.github/workflows/release.yaml:
--------------------------------------------------------------------------------
1 | name: Release to Maven Central
2 |
3 | on:
4 | push:
5 | branches: [ "release/release", "release/milestone" ]
6 |
7 | jobs:
8 | build:
9 | name: Release project
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 |
14 | - name: Check out sources
15 | uses: actions/checkout@v4
16 |
17 | - name: Set up JDK 17
18 | uses: actions/setup-java@v4
19 | with:
20 | distribution: 'temurin'
21 | java-version: 17
22 | cache: 'maven'
23 |
24 | - name: Install GPG key
25 | run: |
26 | echo "${{ secrets.GPG_PRIVATE_KEY }}" > gpg.asc
27 | echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --batch --yes --passphrase-fd 0 --import gpg.asc
28 |
29 | - name: Release to Sonatype OSSRH
30 | env:
31 | SONATYPE_USER: ${{ secrets.OSSRH_S01_TOKEN_USERNAME }}
32 | SONATYPE_PASSWORD: ${{ secrets.OSSRH_S01_TOKEN_PASSWORD }}
33 | MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
34 | run: |
35 | ./mvnw -B clean install -DskipTests
36 | ./mvnw -B clean deploy -Pci,sonatype -s settings.xml
37 |
38 | - name: Setup Graphviz
39 | uses: ts-graphviz/setup-graphviz@v2
40 |
41 | - name: Deploy documentation
42 | env:
43 | ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
44 | ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
45 | run: ./mvnw -B clean deploy -Pdocumentation
46 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | .settings/
3 | .project
4 | .classpath
5 | .factorypath
6 | *.iml
7 | .idea
8 | *.orig
9 | .flattened-pom.xml
10 | .springBeans
11 | credentials.yml
12 | etc/updates.txt
13 |
--------------------------------------------------------------------------------
/.mvn/jvm.config:
--------------------------------------------------------------------------------
1 | --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
2 | --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
3 | --add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
4 | --add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
5 | --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
6 | --add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
7 | --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
8 | --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
9 | --add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
10 | --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
11 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 | wrapperVersion=3.3.2
18 | distributionType=only-script
19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
20 |
--------------------------------------------------------------------------------
/application.yml:
--------------------------------------------------------------------------------
1 | changelog:
2 | repository: spring-projects/spring-hateoas
3 | sections:
4 | - title: ":star: New Features"
5 | labels: ["type: new feature"]
6 | - title: ":bulb: Improvements"
7 | labels: ["type: enhancement"]
8 | - title: ":beetle: Bugs"
9 | labels: ["type: bug"]
10 | - title: ":book: Documentation"
11 | labels: ["in: documentation"]
12 | - title: ":hammer: Dependency Upgrades"
13 | labels: ["type: dependency-upgrade"]
14 |
--------------------------------------------------------------------------------
/etc/backport-ticket.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Format $ticketNumber $targetVersion[]
3 |
4 | sourceGh="GH-$1"
5 | branch=$(git branch --show-current)
6 | json=$(gh issue view $1 --json=title,labels)
7 |
8 | title=$(echo $json | jq -r '.title')
9 | labels=$(echo $json | jq -r '.labels[].name' | paste -sd ',' -)
10 |
11 | number=$1
12 |
13 | # The SHAs of all commits associated with the source ticket
14 | shas=$(git log --grep="$sourceGh" --reverse --format="%H")
15 |
16 | # For each of the target versions
17 | for version in ${@:2}
18 | do
19 | # Turn 1.5.6 into 1.5.x
20 | targetBranch="$(echo "$version" | grep -oE '^[0-9]+\.[0-9]+').x"
21 |
22 | # Checkout target branch and cherry-pick commit
23 | echo "Checking out branch $targetBranch"
24 | git checkout $targetBranch
25 |
26 | # Cherry-pick all previously found SHAs
27 | while IFS= read -r sha
28 | do
29 | echo "Cherry-pick commit $sha from $branch"
30 | git cherry-pick $sha
31 | done <<< $shas
32 |
33 | echo "gh issue create --title \"$title\" --body \"Back-port of $sourceGh.\" --label \"$labels\" --assignee \"@me\" --milestone \"$version\""
34 | number=$(gh issue create --title "$title" --body "Back-port of $sourceGh." --label "$labels" --assignee "@me" --milestone "$version" | awk -F '/' '{print $NF}')
35 | echo "New ticket number: $number"
36 |
37 | # Replace ticket reference with new one
38 | targetGh="GH-$number"
39 | expression="s/$sourceGh/$targetGh/g"
40 | message=$(git log -1 --pretty=format:"%s" | sed $expression)
41 |
42 | # Update commit message to refer to new ticket
43 | echo "Adapt commit message from $sourceGh to $targetGh"
44 | git commit --amend -m "$message"
45 | done
46 |
47 | # Return to original branch
48 | git checkout $branch
49 |
--------------------------------------------------------------------------------
/etc/ide/intellij-formatting.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-projects/spring-hateoas/b50c85045cd678b54b4be77ca72bd1ff05b56b37/etc/ide/intellij-formatting.jar
--------------------------------------------------------------------------------
/etc/mappings.txt:
--------------------------------------------------------------------------------
1 | assertj=AssertJ
2 | jackson-bom=Jackson
3 | junit=JUnit
4 | kotlin=Kotlin
5 | kotlinx-coroutines=Kotlin Koroutines
6 | logback=Logback
7 | lombok=Lombok
8 | mockk=Mockk
9 | reactor-bom=Reactor
10 | slf4j=Slf4j
11 | spring=Spring Framework
12 |
--------------------------------------------------------------------------------
/lombok.config:
--------------------------------------------------------------------------------
1 | lombok.anyConstructor.suppressConstructorProperties=true
2 | lombok.nonNull.exceptionType = IllegalArgumentException
3 | lombok.log.fieldName = LOG
4 | lombok.addLombokGeneratedAnnotation = true
5 | lombok.addNullAnnotations = spring
6 |
--------------------------------------------------------------------------------
/settings.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | sonatype-new
8 | ${env.SONATYPE_USER}
9 | ${env.SONATYPE_PASSWORD}
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/AffordancesSample.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas;
17 |
18 | import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
19 |
20 | import org.springframework.hateoas.SimpleRepresentationModelAssemblerTest.Employee;
21 | import org.springframework.hateoas.mediatype.Affordances;
22 | import org.springframework.http.HttpMethod;
23 |
24 | /**
25 | * Manual usage of {@link Affordances}.
26 | *
27 | * @author Oliver Drotbohm
28 | */
29 | public class AffordancesSample {
30 |
31 | void manualAffordance() {
32 |
33 | // tag::affordances[]
34 | var methodInvocation = methodOn(EmployeeController.class).all();
35 |
36 | var link = Affordances.of(linkTo(methodInvocation).withSelfRel()) // <1>
37 |
38 | .afford(HttpMethod.POST) // <2>
39 | .withInputAndOutput(Employee.class) //
40 | .withName("createEmployee") //
41 |
42 | .andAfford(HttpMethod.GET) // <3>
43 | .withOutput(Employee.class) //
44 | .addParameters(//
45 | QueryParameter.optional("name"), //
46 | QueryParameter.optional("role")) //
47 | .withName("search") //
48 |
49 | .toLink();
50 | // end::affordances[]
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/CollectionJsonApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas;
17 |
18 | import org.springframework.context.annotation.Configuration;
19 | import org.springframework.hateoas.config.EnableHypermediaSupport;
20 | import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
21 |
22 | /**
23 | * @author Greg Turnquist
24 | */
25 | // tag::code[]
26 | @Configuration
27 | @EnableHypermediaSupport(type = HypermediaType.COLLECTION_JSON)
28 | public class CollectionJsonApplication {
29 |
30 | }
31 | // end::code[]
32 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/EmployeeModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas;
17 |
18 | import jakarta.validation.constraints.NotNull;
19 | import jakarta.validation.constraints.Pattern;
20 | import lombok.Data;
21 |
22 | /**
23 | * @author Oliver Drotbohm
24 | */
25 | // tag:hal-forms-model[]
26 | @Data
27 | public class EmployeeModel extends RepresentationModel {
28 |
29 | @NotNull //
30 | private String name;
31 |
32 | @Pattern(regexp = "[A-Z_]") //
33 | private String role;
34 | }
35 | // end:hal-forms-model[]
36 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/ForwardedEnabledConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.hateoas;
18 |
19 | import org.springframework.context.annotation.Bean;
20 | import org.springframework.context.annotation.Configuration;
21 | import org.springframework.web.filter.ForwardedHeaderFilter;
22 | import org.springframework.web.server.adapter.ForwardedHeaderTransformer;
23 |
24 | /**
25 | * @author Greg Turnquist
26 | */
27 | @Configuration
28 | public class ForwardedEnabledConfig {
29 |
30 | // tag::code-1[]
31 | @Bean
32 | ForwardedHeaderFilter forwardedHeaderFilter() {
33 | return new ForwardedHeaderFilter();
34 | }
35 | // end::code-1[]
36 |
37 | // tag::code-2[]
38 | @Bean
39 | ForwardedHeaderTransformer forwardedHeaderTransformer() {
40 | return new ForwardedHeaderTransformer();
41 | }
42 | // end::code-2[]
43 | }
44 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/HalFormsApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas;
17 |
18 | import org.springframework.context.annotation.Configuration;
19 | import org.springframework.hateoas.config.EnableHypermediaSupport;
20 | import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
21 |
22 | /**
23 | * @author Greg Turnquist
24 | */
25 | // tag::code[]
26 | @Configuration
27 | @EnableHypermediaSupport(type = HypermediaType.HAL_FORMS)
28 | public class HalFormsApplication {
29 |
30 | }
31 | // end::code[]
32 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/PaymentProcessingApp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas;
17 |
18 | import org.springframework.context.annotation.Bean;
19 | import org.springframework.context.annotation.Configuration;
20 |
21 | /**
22 | * @author Greg Turnquist
23 | */
24 | // tag::code[]
25 | @Configuration
26 | public class PaymentProcessingApp {
27 |
28 | @Bean
29 | PaymentProcessor paymentProcessor() {
30 | return new PaymentProcessor();
31 | }
32 | }
33 | // end::code[]
34 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/PaymentProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas;
17 |
18 | import org.springframework.hateoas.server.RepresentationModelProcessor;
19 | import org.springframework.hateoas.support.Order;
20 |
21 | /**
22 | * @author Greg Turnquist
23 | */
24 | // tag::code[]
25 | public class PaymentProcessor implements RepresentationModelProcessor> { // <1>
26 |
27 | @Override
28 | public EntityModel process(EntityModel model) {
29 |
30 | model.add( // <2>
31 | Link.of("/payments/{orderId}").withRel(LinkRelation.of("payments")) //
32 | .expand(model.getContent().getOrderId()));
33 |
34 | return model; // <3>
35 | }
36 | }
37 | // end::code[]
38 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/SampleAppConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas;
17 |
18 | import org.springframework.context.annotation.Bean;
19 | import org.springframework.context.annotation.Configuration;
20 | import org.springframework.hateoas.mediatype.hal.HalConfiguration;
21 | import org.springframework.hateoas.mediatype.hal.HalConfiguration.RenderSingleLinks;
22 |
23 | /**
24 | * @author Greg Turnquist
25 | */
26 |
27 | @Configuration
28 | public class SampleAppConfiguration {
29 |
30 | // tag::1[]
31 | @Bean
32 | public HalConfiguration globalPolicy() {
33 | return new HalConfiguration() //
34 | .withRenderSingleLinks(RenderSingleLinks.AS_ARRAY); // <1>
35 | }
36 | // end::1[]
37 |
38 | // tag::2[]
39 | @Bean
40 | public HalConfiguration linkRelationBasedPolicy() {
41 | return new HalConfiguration() //
42 | .withRenderSingleLinksFor( //
43 | IanaLinkRelations.ITEM, RenderSingleLinks.AS_ARRAY) // <1>
44 | .withRenderSingleLinksFor( //
45 | LinkRelation.of("prev"), RenderSingleLinks.AS_SINGLE); // <2>
46 | }
47 | // end::2[]
48 |
49 | // tag::3[]
50 | @Bean
51 | public HalConfiguration patternBasedPolicy() {
52 | return new HalConfiguration() //
53 | .withRenderSingleLinksFor( //
54 | "http*", RenderSingleLinks.AS_ARRAY); // <1>
55 | }
56 | // end::3[]
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/UberApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas;
17 |
18 | import org.springframework.context.annotation.Configuration;
19 | import org.springframework.hateoas.config.EnableHypermediaSupport;
20 | import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
21 |
22 | /**
23 | * @author Greg Turnquist
24 | */
25 | // tag::code[]
26 | @Configuration
27 | @EnableHypermediaSupport(type = HypermediaType.UBER)
28 | public class UberApplication {
29 |
30 | }
31 | // end::code[]
32 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/client/HypermediaConfiguration.java:
--------------------------------------------------------------------------------
1 | package org.springframework.hateoas.client;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.hateoas.config.HypermediaRestTemplateConfigurer;
6 | import org.springframework.hateoas.config.HypermediaWebClientConfigurer;
7 | import org.springframework.web.client.RestTemplate;
8 | import org.springframework.web.reactive.function.client.WebClient;
9 |
10 | @Configuration
11 | public class HypermediaConfiguration {
12 |
13 | // tag::rest-template[]
14 | /**
15 | * Use the {@link HypermediaRestTemplateConfigurer} to configure a {@link RestTemplate}.
16 | */
17 | @Bean
18 | RestTemplate hypermediaRestTemplate(HypermediaRestTemplateConfigurer configurer) { // <1>
19 | return configurer.registerHypermediaTypes(new RestTemplate()); // <2>
20 | }
21 | // end::rest-template[]
22 |
23 | // tag::web-client[]
24 | @Bean
25 | WebClient.Builder hypermediaWebClient(HypermediaWebClientConfigurer configurer) { // <1>
26 | return configurer.registerHypermediaTypes(WebClient.builder()); // <2>
27 | }
28 | // end::web-client[]
29 | }
30 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/mediatype/problem/PaymentResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.problem;
17 |
18 | import java.net.URI;
19 | import java.util.List;
20 | import java.util.UUID;
21 |
22 | /**
23 | * @author Oliver Drotbohm
24 | */
25 | class PaymentResult {
26 |
27 | UUID getPaymentId() {
28 | return UUID.randomUUID();
29 | }
30 |
31 | boolean isSuccess() {
32 | return false;
33 | }
34 |
35 | int getBalance() {
36 | return 30;
37 | }
38 |
39 | UUID getSourceAccountId() {
40 | return UUID.randomUUID();
41 | }
42 |
43 | UUID getTargetAccountId() {
44 | return UUID.randomUUID();
45 | }
46 |
47 | AccountDetails getDetails() {
48 | return new AccountDetails();
49 | }
50 |
51 | static class AccountDetails {
52 | int balance;
53 | List accounts;
54 | }
55 |
56 | int getCost() {
57 | return 50;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/mediatype/problem/PaymentService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.problem;
17 |
18 | /**
19 | * @author Oliver Drotbohm
20 | */
21 | public interface PaymentService {
22 |
23 | PaymentResult issuePayment(long orderId, int amount);
24 | }
25 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/support/Customer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.support;
17 |
18 | import lombok.RequiredArgsConstructor;
19 | import lombok.Value;
20 |
21 | /**
22 | * @author Greg Turnquist
23 | */
24 | @Value
25 | @RequiredArgsConstructor
26 | public class Customer {
27 | private final long customerId;
28 | }
29 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/support/Order.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.support;
17 |
18 | import lombok.RequiredArgsConstructor;
19 | import lombok.Value;
20 |
21 | /**
22 | * @author Greg Turnquist
23 | */
24 | @Value
25 | @RequiredArgsConstructor
26 | public class Order {
27 | private final long orderId;
28 | private final String state;
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/support/Payment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.support;
17 |
18 | import lombok.RequiredArgsConstructor;
19 | import lombok.Value;
20 |
21 | /**
22 | * @author Greg Turnquist
23 | */
24 | @Value
25 | @RequiredArgsConstructor
26 | public class Payment {
27 | private final Order order;
28 | private final double amount;
29 | }
30 |
--------------------------------------------------------------------------------
/src/docs/java/org/springframework/hateoas/support/PaymentController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.support;
17 |
18 | import org.springframework.web.bind.annotation.RestController;
19 |
20 | /**
21 | * @author Greg Turnquist
22 | */
23 | @RestController
24 | public class PaymentController {
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/docs/resources/assemblies/docs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | docs
4 |
5 | dir
6 | zip
7 |
8 | false
9 |
10 |
11 |
14 | src/main/resources
15 |
16 | changelog.txt
17 | license.txt
18 | notice.txt
19 |
20 |
21 | dos
22 |
23 |
24 |
28 | target/generated-docs
29 | reference
30 |
31 |
32 |
36 | target/site/apidocs
37 | api
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/collectionjson/spec-part1.json:
--------------------------------------------------------------------------------
1 | {
2 | "collection": {
3 | "version": "1.0",
4 | "href": "https://example.org/friends/"
5 | }
6 | }
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/collectionjson/spec-part3.json:
--------------------------------------------------------------------------------
1 | {
2 | "collection": {
3 | "version": "1.0",
4 | "href": "https://example.org/friends/", // <1>
5 | "links": [ // <2>
6 | {
7 | "rel": "feed",
8 | "href": "https://example.org/friends/rss"
9 | },
10 | {
11 | "rel": "queries",
12 | "href": "https://example.org/friends/?queries"
13 | },
14 | {
15 | "rel": "template",
16 | "href": "https://example.org/friends/?template"
17 | }
18 | ],
19 | "items": [ // <3>
20 | {
21 | "href": "https://example.org/friends/jdoe",
22 | "data": [ // <4>
23 | {
24 | "name": "fullname",
25 | "value": "J. Doe",
26 | "prompt": "Full Name"
27 | },
28 | {
29 | "name": "email",
30 | "value": "jdoe@example.org",
31 | "prompt": "Email"
32 | }
33 | ],
34 | "links": [ // <5>
35 | {
36 | "rel": "blog",
37 | "href": "https://examples.org/blogs/jdoe",
38 | "prompt": "Blog"
39 | },
40 | {
41 | "rel": "avatar",
42 | "href": "https://examples.org/images/jdoe",
43 | "prompt": "Avatar",
44 | "render": "image"
45 | }
46 | ]
47 | }
48 | ]
49 | }
50 | }
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/collectionjson/spec-part4.json:
--------------------------------------------------------------------------------
1 | {
2 | "collection": {
3 | "version": "1.0",
4 | "href": "https://example.org/friends/",
5 | "queries": [
6 | {
7 | "rel": "search",
8 | "href": "https://example.org/friends/search",
9 | "prompt": "Search",
10 | "data": [
11 | {
12 | "name": "search",
13 | "value": ""
14 | }
15 | ]
16 | }
17 | ]
18 | }
19 | }
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/collectionjson/spec-part5.json:
--------------------------------------------------------------------------------
1 | {
2 | "collection": {
3 | "version": "1.0",
4 | "href": "https://example.org/friends/",
5 | "template": {
6 | "data": [
7 | {
8 | "name": "full-name",
9 | "value": "",
10 | "prompt": "Full Name"
11 | },
12 | {
13 | "name": "email",
14 | "value": "",
15 | "prompt": "Email"
16 | },
17 | {
18 | "name": "blog",
19 | "value": "",
20 | "prompt": "Blog"
21 | },
22 | {
23 | "name": "avatar",
24 | "value": "",
25 | "prompt": "Avatar"
26 | }
27 | ]
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/collectionjson/spec-part6.json:
--------------------------------------------------------------------------------
1 | {
2 | "collection": {
3 | "version": "1.0",
4 | "href": "https://example.org/friends/",
5 | "error": {
6 | "title": "Server Error",
7 | "code": "X1C2",
8 | "message": "The server have encountered an error, please wait and try again."
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/collectionjson/spec-part7.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": {
3 | "data": [
4 | {
5 | "name": "full-name",
6 | "value": "W. Chandry"
7 | },
8 | {
9 | "name": "email",
10 | "value": "wchandry@example.org"
11 | },
12 | {
13 | "name": "blog",
14 | "value": "https://example.org/blogs/wchandry"
15 | },
16 | {
17 | "name": "avatar",
18 | "value": "https://example.org/images/wchandry"
19 | }
20 | ]
21 | }
22 | }
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/hal/forms/hal-forms-sample-with-notes.json:
--------------------------------------------------------------------------------
1 | {
2 | "firstName" : "Frodo",
3 | "lastName" : "Baggins",
4 | "role" : "ring bearer",
5 | "_links" : {
6 | "self" : {
7 | "href" : "http://localhost:8080/employees/1"
8 | }
9 | },
10 | "_templates" : {
11 | "default" : {
12 | "method" : "put",
13 | "properties" : [ {
14 | "name" : "name",
15 | "required" : true
16 | }, {
17 | "name" : "role",
18 | "regex" : "[A-Z_]"
19 | } ]
20 | },
21 | "partiallyUpdateEmployee" : { // <5>
22 | "method" : "patch", // <6>
23 | "properties" : [ {
24 | "name" : "name"
25 | }, {
26 | "name" : "role",
27 | "regex" : "[A-Z_]"
28 | } ]
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/hal/forms/hal-forms-sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "firstName" : "Frodo",
3 | "lastName" : "Baggins",
4 | "role" : "ring bearer",
5 | "_links" : {
6 | "self" : {
7 | "href" : "http://localhost:8080/employees/1"
8 | }
9 | },
10 | "_templates" : {
11 | "default" : {
12 | "method" : "put",
13 | "properties" : [ {
14 | "name" : "firstName",
15 | "required" : true
16 | }, {
17 | "name" : "lastName",
18 | "required" : true
19 | }, {
20 | "name" : "role",
21 | "required" : true
22 | } ]
23 | },
24 | "partiallyUpdateEmployee" : {
25 | "method" : "patch",
26 | "properties" : [ {
27 | "name" : "firstName",
28 | "required" : false
29 | }, {
30 | "name" : "lastName",
31 | "required" : false
32 | }, {
33 | "name" : "role",
34 | "required" : false
35 | } ]
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/hal/hal-multiple-entry-link-relation.json:
--------------------------------------------------------------------------------
1 | {
2 | "_links": {
3 | "item": [
4 | { "href": "https://myhost/cart/42" },
5 | { "href": "https://myhost/inventory/12" }
6 | ]
7 | },
8 | "customer": "Dave Matthews"
9 | }
10 |
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/hal/hal-single-entry-link-relation-array.json:
--------------------------------------------------------------------------------
1 | {
2 | "_links": {
3 | "item": [{ "href": "https://myhost/inventory/12" }]
4 | },
5 | "customer": "Dave Matthews"
6 | }
7 |
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/hal/hal-single-entry-link-relation-object.json:
--------------------------------------------------------------------------------
1 | {
2 | "_links": {
3 | "item": { "href": "https://myhost/inventory/12" }
4 | },
5 | "customer": "Dave Matthews"
6 | }
7 |
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/hal/hal-with-curies.json:
--------------------------------------------------------------------------------
1 | {
2 | "_links": {
3 | "self": {
4 | "href": "https://myhost/person/1"
5 | },
6 | "curies": {
7 | "name": "ex",
8 | "href": "https://example.com/rels/{rel}",
9 | "templated": true
10 | },
11 | "ex:orders": {
12 | "href": "https://myhost/person/1/orders"
13 | }
14 | },
15 | "firstname": "Dave",
16 | "lastname": "Matthews"
17 | }
18 |
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/problem/response.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "https://example.com/probs/out-of-credit",
3 | "title": "You do not have enough credit.",
4 | "detail": "Your current balance is 30, but that costs 50.",
5 | "instance": "/account/12345/msgs/abc",
6 | "balance": 30,
7 | "accounts": ["/account/12345",
8 | "/account/67890"]
9 | }
10 |
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/mediatype/uber/uber-sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "uber" : {
3 | "version" : "1.0",
4 | "data" : [ {
5 | "rel" : [ "self" ],
6 | "url" : "/employees/1"
7 | }, {
8 | "name" : "employee",
9 | "data" : [ {
10 | "name" : "role",
11 | "value" : "ring bearer"
12 | }, {
13 | "name" : "name",
14 | "value" : "Frodo"
15 | } ]
16 | } ]
17 | }
18 | }
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/order-plain.json:
--------------------------------------------------------------------------------
1 | {
2 | "orderId" : "42",
3 | "state" : "AWAITING_PAYMENT",
4 | "_links" : {
5 | "self" : {
6 | "href" : "http://localhost/orders/999"
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/src/docs/resources/org/springframework/hateoas/docs/order-with-payment-link.json:
--------------------------------------------------------------------------------
1 | {
2 | "orderId" : "42",
3 | "state" : "AWAITING_PAYMENT",
4 | "_links" : {
5 | "self" : {
6 | "href" : "http://localhost/orders/999"
7 | },
8 | "payments" : { // <1>
9 | "href" : "/payments/42" // <2>
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/main/asciidoc/index.adoc:
--------------------------------------------------------------------------------
1 | = Spring HATEOAS - Reference Documentation
2 | Oliver Drotbohm; Greg Turnquist; Jay Bryant
3 | :revnumber: {version}
4 | :revdate: {localdate}
5 | :toc: left
6 | :hide-uri-scheme:
7 |
8 | This project provides some APIs to ease creating REST representations that follow the https://en.wikipedia.org/wiki/HATEOAS[HATEOAS] principle when working with Spring and especially Spring MVC. The core problem it tries to address is link creation and representation assembly.
9 |
10 | (C) 2012-2021 The original authors.
11 |
12 | NOTE: Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
13 |
14 | [[preface]]
15 | == Preface
16 | include::migrate-to-1.0.adoc[leveloffset=+2]
17 | include::fundamentals.adoc[leveloffset=+1]
18 | include::server.adoc[leveloffset=+1]
19 | include::mediatypes.adoc[leveloffset=+1]
20 | include::configuration.adoc[leveloffset=+1]
21 | include::client.adoc[leveloffset=+1]
22 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/InputType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas;
17 |
18 | import static java.lang.annotation.ElementType.*;
19 | import static java.lang.annotation.RetentionPolicy.*;
20 |
21 | import java.lang.annotation.Documented;
22 | import java.lang.annotation.Retention;
23 | import java.lang.annotation.Target;
24 |
25 | /**
26 | * Annotation to declare a dedicated input type for a property of an representation model. Input types are usually
27 | * derived from the property's type or JSR-303 validation annotations. Use this annotation to override the type.
28 | *
29 | * Values are usually constrained by {@link HtmlInputType} as most media types align with those semantically. That said,
30 | * the annotation doesn't prescribe the usage of those and is open for extensions.
31 | *
32 | * @author Oliver Drotbohm
33 | * @see HtmlInputType
34 | * @since 1.3
35 | * @soundtrack Boney M - Daddy Cool (Take The Heat Off Me)
36 | */
37 | @Documented
38 | @Retention(RUNTIME)
39 | @Target({ FIELD, METHOD, ANNOTATION_TYPE })
40 | public @interface InputType {
41 | String value();
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/NonComposite.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas;
17 |
18 | import static java.lang.annotation.ElementType.*;
19 | import static java.lang.annotation.RetentionPolicy.*;
20 |
21 | import java.lang.annotation.Retention;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * Annotation to be used in combination with {@link RequestParam} to indicate that collection based values are supposed
26 | * to be rendered as non-composite values, i.e. like {@code param=value1,value2,value3} rather than
27 | * {@code param=value1¶m=value2} when generating links by pointing to controller methods.
28 | *
29 | * @author Oliver Drotbohm
30 | * @since 1.4
31 | */
32 | @Retention(RUNTIME)
33 | @Target({ PARAMETER, ANNOTATION_TYPE })
34 | public @interface NonComposite {}
35 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/aot/HateoasTypesRuntimeHints.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.aot;
17 |
18 | import org.jspecify.annotations.Nullable;
19 | import org.springframework.aot.hint.RuntimeHints;
20 | import org.springframework.aot.hint.RuntimeHintsRegistrar;
21 | import org.springframework.hateoas.RepresentationModel;
22 |
23 | /**
24 | * Registers reflection metadata for {@link RepresentationModel} types.
25 | *
26 | * @author Oliver Drotbohm
27 | */
28 | class HateoasTypesRuntimeHints implements RuntimeHintsRegistrar {
29 |
30 | /*
31 | * (non-Javadoc)
32 | * @see org.springframework.aot.hint.RuntimeHintsRegistrar#registerHints(org.springframework.aot.hint.RuntimeHints, java.lang.ClassLoader)
33 | */
34 | @Override
35 | public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
36 |
37 | var packageName = RepresentationModel.class.getPackageName();
38 | var reflection = hints.reflection();
39 |
40 | AotUtils.registerTypesForReflection(packageName, reflection);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/aot/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * AOT support.
3 | *
4 | * @author Christoph Strobl
5 | * @author Oliver Drotbohm
6 | */
7 | @org.jspecify.annotations.NullMarked
8 | package org.springframework.hateoas.aot;
9 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/client/TraversonDefaults.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.client;
17 |
18 | import java.util.Collection;
19 | import java.util.List;
20 |
21 | import org.springframework.http.MediaType;
22 | import org.springframework.http.converter.HttpMessageConverter;
23 |
24 | /**
25 | * SPI that exposes {@link HttpMessageConverter}s and {@link LinkDiscoverer}s to be used by default by
26 | * {@link Traverson}. Not intended for public implementation.
27 | *
28 | * @author Oliver Drotbohm
29 | */
30 | public interface TraversonDefaults {
31 |
32 | /**
33 | * Returns the {@link HttpMessageConverter} instances to be registered for the given {@link MediaType}s.
34 | *
35 | * @param mediaTypes will never be {@literal null}.
36 | * @return
37 | */
38 | List> getHttpMessageConverters(Collection mediaTypes);
39 |
40 | /**
41 | * Returns the {@link LinkDiscoverer}s to be registered by default for the given {@link MediaType}s.
42 | *
43 | * @param mediaTypes will never be {@literal null}.
44 | * @return
45 | */
46 | List getLinkDiscoverers(Collection mediaTypes);
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/client/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Client side support.
3 | */
4 | @org.jspecify.annotations.NullMarked
5 | package org.springframework.hateoas.client;
6 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/config/HypermediaRestTemplateConfigurer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.config;
17 |
18 | import org.springframework.web.client.RestTemplate;
19 |
20 | /**
21 | * Assembles hypermedia-based message converters and applies them to an existing {@link RestTemplate}.
22 | *
23 | * @author Greg Turnquist
24 | * @since 1.1
25 | */
26 | public class HypermediaRestTemplateConfigurer {
27 |
28 | private final WebConverters converters;
29 |
30 | /**
31 | * Creates a new {@link HypermediaRestTemplateConfigurer} using the {@link WebConverters}.
32 | *
33 | * @param converters
34 | */
35 | HypermediaRestTemplateConfigurer(WebConverters converters) {
36 | this.converters = converters;
37 | }
38 |
39 | /**
40 | * Insert hypermedia-aware message converters in front of any other existing message converters.
41 | *
42 | * @param template
43 | * @return {@link RestTemplate} capable of speaking hypermedia.
44 | */
45 | public RestTemplate registerHypermediaTypes(RestTemplate template) {
46 |
47 | converters.augmentClient(template.getMessageConverters());
48 |
49 | return template;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/config/MediaTypeConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.config;
17 |
18 | import java.util.Collection;
19 |
20 | import org.springframework.http.MediaType;
21 |
22 | /**
23 | * SPI used to register internal media types through spring.factories.
24 | *
25 | * WARNING: Do NOT implement this interface if you are coding a custom media type. See "Custom media type configuration" in the reference docs.
26 | *
27 | * @author Oliver Drotbohm
28 | * @author Greg Turnquist
29 | * @see HypermediaMappingInformation
30 | */
31 | public interface MediaTypeConfigurationProvider {
32 |
33 | /**
34 | * Returns the primary Spring configuration class to be bootstrapped for the given media type.
35 | *
36 | * @return
37 | */
38 | Class extends HypermediaMappingInformation> getConfiguration();
39 |
40 | /**
41 | * Returns whether the provider supports any of the given {@link MediaType}s. Used to select the providers to be
42 | * included into a configuration setup in case the media types to be enabled are explicitly defined.
43 | *
44 | * @param mediaTypes will never be {@literal null}.
45 | * @return
46 | */
47 | boolean supportsAny(Collection mediaTypes);
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/config/WebMvcEntityLinksConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.config;
17 |
18 | import org.springframework.beans.factory.ObjectProvider;
19 | import org.springframework.context.annotation.Bean;
20 | import org.springframework.context.annotation.Configuration;
21 | import org.springframework.hateoas.server.core.ControllerEntityLinksFactoryBean;
22 | import org.springframework.hateoas.server.mvc.WebMvcLinkBuilderFactory;
23 | import org.springframework.stereotype.Controller;
24 |
25 | /**
26 | * Spring WebMVC specific bean definitions to support {@link EntityLinks}.
27 | *
28 | * @author Greg Turnquist
29 | * @author Oliver Gierke
30 | */
31 | @Configuration(proxyBeanMethods = false)
32 | class WebMvcEntityLinksConfiguration extends EntityLinksConfiguration {
33 |
34 | @Bean
35 | ControllerEntityLinksFactoryBean webMvcEntityLinks(ObjectProvider linkBuilderFactory) {
36 |
37 | ControllerEntityLinksFactoryBean factory = new ControllerEntityLinksFactoryBean();
38 | factory.setAnnotation(Controller.class);
39 | factory.setLinkBuilderFactory(linkBuilderFactory.getIfAvailable(WebMvcLinkBuilderFactory::new));
40 |
41 | return factory;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/config/WebTestHateoasConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.config;
17 |
18 | import java.util.List;
19 |
20 | import org.springframework.beans.factory.ObjectProvider;
21 | import org.springframework.context.annotation.Bean;
22 | import org.springframework.context.annotation.Configuration;
23 | import org.springframework.context.annotation.Lazy;
24 |
25 | import com.fasterxml.jackson.databind.ObjectMapper;
26 |
27 | /**
28 | * Configuration for Spring TEST-specific things
29 | *
30 | * @author Greg Turnquist
31 | * @author Oliver Drotbohm
32 | * @since 1.1
33 | */
34 | @Configuration(proxyBeanMethods = false)
35 | class WebTestHateoasConfiguration {
36 |
37 | @Bean
38 | @Lazy
39 | HypermediaWebTestClientConfigurer webTestClientConfigurer(ObjectProvider mapper,
40 | List hypermediaTypes) {
41 | return new HypermediaWebTestClientConfigurer(mapper.getIfAvailable(ObjectMapper::new), hypermediaTypes);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/config/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Spring container configuration support.
3 | */
4 | @org.jspecify.annotations.NullMarked
5 | package org.springframework.hateoas.config;
6 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/AffordanceModelFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype;
17 |
18 | import org.springframework.hateoas.AffordanceModel;
19 | import org.springframework.http.MediaType;
20 |
21 | /**
22 | * SPI for media type implementations to create a specific {@link AffordanceModel} for a {@link ConfiguredAffordance}.
23 | *
24 | * @author Greg Turnquist
25 | * @author Oliver Gierke
26 | */
27 | public interface AffordanceModelFactory {
28 |
29 | /**
30 | * Declare the {@link MediaType} this factory supports.
31 | *
32 | * @return
33 | */
34 | MediaType getMediaType();
35 |
36 | /**
37 | * Return the {@link AffordanceModel} for the given {@link ConfiguredAffordance}.
38 | *
39 | * @param configured will never be {@literal null}.
40 | * @return must not be {@literal null}.
41 | * @since 1.3
42 | */
43 | AffordanceModel getAffordanceModel(ConfiguredAffordance configured);
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/AffordanceOperations.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype;
17 |
18 | import org.springframework.hateoas.Link;
19 |
20 | /**
21 | * Operations commons to all builder APIs.
22 | *
23 | * @author Oliver Drotbohm
24 | * @see ConfigurableAffordance
25 | */
26 | public interface AffordanceOperations {
27 |
28 | /**
29 | * Returns a {@link Link} equipped with the {@link Affordance} currently under construction.
30 | *
31 | * @return will never be {@literal null}.
32 | */
33 | Link toLink();
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/DefaultOnlyMessageResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype;
17 |
18 | import org.jspecify.annotations.Nullable;
19 | import org.springframework.context.MessageSourceResolvable;
20 |
21 | /**
22 | * {@link MessageResolver} to always resort to the {@link MessageSourceResolvable}'s default message.
23 | *
24 | * @author Oliver Drotbohm
25 | */
26 | enum DefaultOnlyMessageResolver implements MessageResolver {
27 |
28 | INSTANCE;
29 |
30 | /*
31 | * (non-Javadoc)
32 | * @see org.springframework.hateoas.mediatype.MessageResolver#resolve(org.springframework.context.MessageSourceResolvable)
33 | */
34 | @Nullable
35 | @Override
36 | public String resolve(MessageSourceResolvable resolvable) {
37 | return resolvable.getDefaultMessage();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/InputTypeFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype;
17 |
18 | import org.jspecify.annotations.Nullable;
19 |
20 | /**
21 | * SPI interface for components that can derive an input type from a {@link ResolvableType}. Primary usage to enable to
22 | * default the resolution to use HTML based {@link org.springframework.hateoas.mediatype.html.HtmlInputType} without
23 | * creating a package cycle. If you want to replace that implementation with a different one, register it in
24 | * {@code META-INF/spring.factories}.
25 | *
26 | * @author Oliver Drotbohm
27 | * @since 1.3
28 | */
29 | public interface InputTypeFactory {
30 |
31 | /**
32 | * Derive an input type from the given {@link ResolvableType}.
33 | *
34 | * @param type type to resolve the input type for, will never be {@literal null}.
35 | * @return the input type for the given type or {@literal null} if no type could be derived.
36 | */
37 | @Nullable
38 | String getInputType(Class> type);
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/JacksonHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype;
17 |
18 | import org.springframework.hateoas.CollectionModel;
19 | import org.springframework.hateoas.EntityModel;
20 |
21 | import com.fasterxml.jackson.databind.JavaType;
22 |
23 | /**
24 | * Jackson utility methods.
25 | */
26 | public final class JacksonHelper {
27 |
28 | /**
29 | * Navigate a chain of parametric types (e.g. Resources<Resource<String>>) until you find the innermost type (String).
30 | *
31 | * @param contentType
32 | * @return
33 | */
34 | public static JavaType findRootType(JavaType contentType) {
35 |
36 | if (contentType.hasGenericTypes()) {
37 | return findRootType(contentType.containedType(0));
38 | } else {
39 | return contentType;
40 | }
41 | }
42 |
43 | /**
44 | * Is this a {@literal Resources>}?
45 | *
46 | * @param type
47 | * @return
48 | */
49 | public static boolean isResourcesOfResource(JavaType type) {
50 |
51 | return
52 | CollectionModel.class.isAssignableFrom(type.getRawClass())
53 | &&
54 | EntityModel.class.isAssignableFrom(type.containedType(0).getRawClass());
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/MediaTypeConfigurationCustomizer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype;
17 |
18 | /**
19 | * Callback interface to customize media type-specific configuration. Declare instances of the interface as bean methods
20 | * in Spring configuration.
21 | *
22 | * @author Oliver Drotbohm
23 | * @since 2.2
24 | */
25 | public interface MediaTypeConfigurationCustomizer {
26 |
27 | /**
28 | * Customize the given configuration instance.
29 | *
30 | * @param configuration will never be {@literal null}.
31 | * @return must not be {@literal null}.
32 | */
33 | T customize(T configuration);
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/alps/AlpsLinkDiscoverer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.alps;
17 |
18 | import org.springframework.hateoas.MediaTypes;
19 | import org.springframework.hateoas.client.JsonPathLinkDiscoverer;
20 |
21 | /**
22 | * {@link LinkDiscoverer} implementation to find ALPS-based links.
23 | *
24 | * @author Greg Turnquist
25 | */
26 | public class AlpsLinkDiscoverer extends JsonPathLinkDiscoverer {
27 |
28 | public AlpsLinkDiscoverer() {
29 | super("$.descriptors[?(@.name == '%s')].href", MediaTypes.ALPS_JSON);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/alps/Format.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.alps;
17 |
18 | import java.util.Locale;
19 |
20 | /**
21 | * Enum for all ALPS doc formats.
22 | *
23 | * @author Oliver Gierke
24 | * @author Greg Turnquist
25 | * @since 0.15
26 | * @see http://alps.io/spec/#prop-format
27 | */
28 | public enum Format {
29 |
30 | TEXT, HTML, ASCIIDOC, MARKDOWN;
31 |
32 | /*
33 | * (non-Javadoc)
34 | * @see java.lang.Enum#toString()
35 | */
36 | public String toString() {
37 | return name().toLowerCase(Locale.US);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/alps/Type.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.alps;
17 |
18 | import java.util.Locale;
19 |
20 | /**
21 | * An enum for ALPS descriptor types
22 | *
23 | * @author Oliver Gierke
24 | * @author Greg Turnquist
25 | * @since 0.15
26 | * @see http://alps.io/spec/#prop-type
27 | */
28 | public enum Type {
29 |
30 | SEMANTIC, SAFE, IDEMPOTENT, UNSAFE;
31 |
32 | /*
33 | * (non-Javadoc)
34 | * @see java.lang.Enum#toString()
35 | */
36 | public String toString() {
37 | return name().toLowerCase(Locale.US);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/alps/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Value objects to build ALPS metadata.
3 | *
4 | * @see https://alps.io
5 | */
6 | @org.jspecify.annotations.NullMarked
7 | package org.springframework.hateoas.mediatype.alps;
8 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonAffordanceModelFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.collectionjson;
17 |
18 | import org.springframework.hateoas.AffordanceModel;
19 | import org.springframework.hateoas.MediaTypes;
20 | import org.springframework.hateoas.mediatype.AffordanceModelFactory;
21 | import org.springframework.hateoas.mediatype.ConfiguredAffordance;
22 | import org.springframework.http.MediaType;
23 |
24 | /**
25 | * Factory for creating {@link CollectionJsonAffordanceModel}s.
26 | *
27 | * @author Greg Turnquist
28 | * @author Oliver Drotbohm
29 | */
30 | class CollectionJsonAffordanceModelFactory implements AffordanceModelFactory {
31 |
32 | /*
33 | * (non-Javadoc)
34 | * @see org.springframework.hateoas.mediatype.AffordanceModelFactory#getAffordanceModel(org.springframework.hateoas.mediatype.ConfiguredAffordance)
35 | */
36 | @Override
37 | public AffordanceModel getAffordanceModel(ConfiguredAffordance configured) {
38 | return new CollectionJsonAffordanceModel(configured);
39 | }
40 |
41 | /*
42 | * (non-Javadoc)
43 | * @see org.springframework.hateoas.mediatype.AffordanceModelFactory#getMediaType()
44 | */
45 | @Override
46 | public MediaType getMediaType() {
47 | return MediaTypes.COLLECTION_JSON;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionJsonMediaTypeConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.collectionjson;
17 |
18 | import java.util.Collection;
19 |
20 | import org.springframework.hateoas.MediaTypes;
21 | import org.springframework.hateoas.config.HypermediaMappingInformation;
22 | import org.springframework.hateoas.config.MediaTypeConfigurationProvider;
23 | import org.springframework.http.MediaType;
24 |
25 | /**
26 | * {@link MediaTypeConfigurationProvider} for Collection/JSON.
27 | *
28 | * @author Oliver Drotbohm
29 | */
30 | class CollectionJsonMediaTypeConfigurationProvider implements MediaTypeConfigurationProvider {
31 |
32 | /*
33 | * (non-Javadoc)
34 | * @see org.springframework.hateoas.config.MediaTypeConfigurationProvider#getConfiguration()
35 | */
36 | @Override
37 | public Class extends HypermediaMappingInformation> getConfiguration() {
38 | return CollectionJsonMediaTypeConfiguration.class;
39 | }
40 |
41 | /*
42 | * (non-Javadoc)
43 | * @see org.springframework.hateoas.config.MediaTypeConfigurationProvider#supportsAny(java.util.Collection)
44 | */
45 | @Override
46 | public boolean supportsAny(Collection mediaTypes) {
47 | return mediaTypes.contains(MediaTypes.COLLECTION_JSON);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/collectionjson/CollectionRepresentationModelMixin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.collectionjson;
17 |
18 | import org.springframework.hateoas.CollectionModel;
19 | import org.springframework.hateoas.mediatype.collectionjson.Jackson2CollectionJsonModule.CollectionJsonResourcesDeserializer;
20 |
21 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
22 |
23 | /**
24 | * Jackson 2 mixin to invoke the related serializer/deserizer.
25 | *
26 | * @author Greg Turnquist
27 | */
28 | @JsonDeserialize(using = CollectionJsonResourcesDeserializer.class)
29 | abstract class CollectionRepresentationModelMixin extends CollectionModel {
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/collectionjson/EntityRepresentationModelMixin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.collectionjson;
17 |
18 | import org.springframework.hateoas.EntityModel;
19 | import org.springframework.hateoas.mediatype.collectionjson.Jackson2CollectionJsonModule.CollectionJsonResourceDeserializer;
20 |
21 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
22 |
23 | /**
24 | * Jackson 2 mixin to invoke the related serializer/deserizer.
25 | *
26 | * @author Greg Turnquist
27 | */
28 | @JsonDeserialize(using = CollectionJsonResourceDeserializer.class)
29 | abstract class EntityRepresentationModelMixin extends EntityModel {
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/collectionjson/PagedResourcesMixin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.collectionjson;
17 |
18 | import org.springframework.hateoas.PagedModel;
19 | import org.springframework.hateoas.mediatype.collectionjson.Jackson2CollectionJsonModule.CollectionJsonPagedResourcesDeserializer;
20 |
21 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
22 |
23 | /**
24 | * Jackson 2 mixin to handle {@link PagedModel}.
25 | *
26 | * @author Greg Turnquist
27 | */
28 | @JsonDeserialize(using = CollectionJsonPagedResourcesDeserializer.class)
29 | abstract class PagedResourcesMixin extends PagedModel {
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/collectionjson/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Value objects to build Collection+JSON representations.
3 | */
4 | @org.jspecify.annotations.NullMarked
5 | package org.springframework.hateoas.mediatype.collectionjson;
6 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/hal/CollectionModelMixin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.hal;
17 |
18 | import java.util.Collection;
19 |
20 | import org.springframework.hateoas.CollectionModel;
21 |
22 | import com.fasterxml.jackson.annotation.JsonInclude;
23 | import com.fasterxml.jackson.annotation.JsonInclude.Include;
24 | import com.fasterxml.jackson.annotation.JsonProperty;
25 | import com.fasterxml.jackson.annotation.JsonPropertyOrder;
26 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
27 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
28 |
29 | /**
30 | * Custom mixin to to render collection content as {@literal _embedded}.
31 | *
32 | * @author Alexander Baetz
33 | * @author Oliver Gierke
34 | * @author Greg Turnquist
35 | */
36 | @JsonPropertyOrder({ "content", "links" })
37 | public abstract class CollectionModelMixin extends CollectionModel {
38 |
39 | @Override
40 | @JsonProperty("_embedded")
41 | @JsonInclude(Include.NON_EMPTY)
42 | @JsonSerialize(using = Jackson2HalModule.HalResourcesSerializer.class)
43 | @JsonDeserialize(using = Jackson2HalModule.HalResourcesDeserializer.class)
44 | public abstract Collection getContent();
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/hal/HalMediaTypeConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.hal;
17 |
18 | import java.util.Collection;
19 |
20 | import org.springframework.hateoas.MediaTypes;
21 | import org.springframework.hateoas.config.HypermediaMappingInformation;
22 | import org.springframework.hateoas.config.MediaTypeConfigurationProvider;
23 | import org.springframework.http.MediaType;
24 |
25 | /**
26 | * {@link MediaTypeConfigurationProvider} for HAL.
27 | *
28 | * @author Oliver Drotbohm
29 | */
30 | class HalMediaTypeConfigurationProvider implements MediaTypeConfigurationProvider {
31 |
32 | /*
33 | * (non-Javadoc)
34 | * @see org.springframework.hateoas.config.HyperMediaTypeProvider#getConfiguration()
35 | */
36 | @Override
37 | public Class extends HypermediaMappingInformation> getConfiguration() {
38 | return HalMediaTypeConfiguration.class;
39 | }
40 |
41 | /*
42 | * (non-Javadoc)
43 | * @see org.springframework.hateoas.config.HyperMediaTypeProvider#supportsAny(java.util.Collection)
44 | */
45 | @Override
46 | public boolean supportsAny(Collection mediaTypes) {
47 |
48 | return mediaTypes.contains(MediaTypes.HAL_JSON)
49 | || mediaTypes.contains(MediaTypes.VND_HAL_JSON);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/hal/RepresentationModelMixin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.hal;
17 |
18 | import org.springframework.hateoas.Links;
19 | import org.springframework.hateoas.RepresentationModel;
20 |
21 | import com.fasterxml.jackson.annotation.JsonInclude;
22 | import com.fasterxml.jackson.annotation.JsonInclude.Include;
23 | import com.fasterxml.jackson.annotation.JsonProperty;
24 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
25 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
26 |
27 | /**
28 | * Custom mixin to render {@link Link}s in HAL.
29 | *
30 | * @author Alexander Baetz
31 | * @author Oliver Gierke
32 | * @author Greg Turnquist
33 | */
34 | public abstract class RepresentationModelMixin extends RepresentationModel {
35 |
36 | @Override
37 | @JsonProperty("_links")
38 | @JsonInclude(Include.NON_EMPTY)
39 | @JsonSerialize(using = Jackson2HalModule.HalLinkListSerializer.class)
40 | @JsonDeserialize(using = Jackson2HalModule.HalLinkListDeserializer.class)
41 | public abstract Links getLinks();
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsAffordanceModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.hal.forms;
17 |
18 | import org.springframework.hateoas.AffordanceModel;
19 | import org.springframework.hateoas.mediatype.ConfiguredAffordance;
20 |
21 | /**
22 | * {@link AffordanceModel} for a HAL-FORMS {@link MediaType}.
23 | *
24 | * @author Greg Turnquist
25 | * @author Oliver Gierke
26 | */
27 | class HalFormsAffordanceModel extends AffordanceModel {
28 |
29 | public HalFormsAffordanceModel(ConfiguredAffordance configured) {
30 | super(configured.getNameOrDefault(), configured.getTarget(), configured.getMethod(), configured.getInputMetadata(),
31 | configured.getQueryParameters(), configured.getOutputMetadata());
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsAffordanceModelFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.hal.forms;
17 |
18 | import org.springframework.hateoas.AffordanceModel;
19 | import org.springframework.hateoas.MediaTypes;
20 | import org.springframework.hateoas.mediatype.AffordanceModelFactory;
21 | import org.springframework.hateoas.mediatype.ConfiguredAffordance;
22 | import org.springframework.http.MediaType;
23 |
24 | /**
25 | * Factory for creating {@link HalFormsAffordanceModel}s.
26 | *
27 | * @author Greg Turnquist
28 | * @author Oliver Gierke
29 | */
30 | class HalFormsAffordanceModelFactory implements AffordanceModelFactory {
31 |
32 | private final MediaType mediaType = MediaTypes.HAL_FORMS_JSON;
33 |
34 | /*
35 | * (non-Javadoc)
36 | * @see org.springframework.hateoas.mediatype.AffordanceModelFactory#getAffordanceModel(org.springframework.hateoas.mediatype.ConfiguredAffordance)
37 | */
38 | @Override
39 | public AffordanceModel getAffordanceModel(ConfiguredAffordance configured) {
40 | return new HalFormsAffordanceModel(configured);
41 | }
42 |
43 | public MediaType getMediaType() {
44 | return this.mediaType;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsLinkDiscoverer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.hal.forms;
17 |
18 | import org.springframework.hateoas.MediaTypes;
19 | import org.springframework.hateoas.mediatype.hal.HalLinkDiscoverer;
20 |
21 | /**
22 | * HAL-FORMS based {@link JsonPathLinkDiscoverer}.
23 | *
24 | * @author Greg Turnquist
25 | * @author Oliver Gierke
26 | */
27 | public class HalFormsLinkDiscoverer extends HalLinkDiscoverer {
28 |
29 | public HalFormsLinkDiscoverer() {
30 | super(MediaTypes.HAL_FORMS_JSON);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/hal/forms/HalFormsMediaTypeConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.hal.forms;
17 |
18 | import java.util.Collection;
19 |
20 | import org.springframework.hateoas.MediaTypes;
21 | import org.springframework.hateoas.config.HypermediaMappingInformation;
22 | import org.springframework.hateoas.config.MediaTypeConfigurationProvider;
23 | import org.springframework.http.MediaType;
24 |
25 | /**
26 | * {@link MediaTypeConfigurationProvider} for HAL Forms.
27 | *
28 | * @author Oliver Drotbohm
29 | */
30 | class HalFormsMediaTypeConfigurationProvider implements MediaTypeConfigurationProvider {
31 |
32 | /*
33 | * (non-Javadoc)
34 | * @see org.springframework.hateoas.config.MediaTypeConfigurationProvider#getConfiguration()
35 | */
36 | @Override
37 | public Class extends HypermediaMappingInformation> getConfiguration() {
38 | return HalFormsMediaTypeConfiguration.class;
39 | }
40 |
41 | /*
42 | * (non-Javadoc)
43 | * @see org.springframework.hateoas.config.MediaTypeConfigurationProvider#supportsAny(java.util.Collection)
44 | */
45 | @Override
46 | public boolean supportsAny(Collection mediaTypes) {
47 | return mediaTypes.contains(MediaTypes.HAL_FORMS_JSON);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/hal/forms/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * HAL-FORMS extension media type.
3 | */
4 | @org.jspecify.annotations.NullMarked
5 | package org.springframework.hateoas.mediatype.hal.forms;
6 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/hal/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * HAL-specific extensions, SPIs and Jackson customizations.
3 | *
4 | * @see http://stateless.co/hal_specification.html
5 | */
6 | @org.jspecify.annotations.NullMarked
7 | package org.springframework.hateoas.mediatype.hal;
8 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/html/HtmlInputTypeFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.html;
17 |
18 | import org.jspecify.annotations.Nullable;
19 | import org.springframework.hateoas.mediatype.InputTypeFactory;
20 |
21 | /**
22 | * An {@link InputTypeFactory} based on {@link HtmlInputType}.
23 | *
24 | * @author Oliver Drotbohm
25 | * @since 1.3
26 | */
27 | class HtmlInputTypeFactory implements InputTypeFactory {
28 |
29 | /*
30 | *
31 | * (non-Javadoc)
32 | * @see org.springframework.hateoas.mediatype.InputTypeFactory#getInputType(java.lang.Class)
33 | */
34 | @Nullable
35 | @Override
36 | public String getInputType(Class> type) {
37 |
38 | HtmlInputType inputType = HtmlInputType.from(type);
39 |
40 | return inputType == null ? null : inputType.value();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/html/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Support for HTML media type.
3 | */
4 | @org.jspecify.annotations.NullMarked
5 | package org.springframework.hateoas.mediatype.html;
6 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * General media type support.
3 | */
4 | @org.jspecify.annotations.NullMarked
5 | package org.springframework.hateoas.mediatype;
6 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/problem/HttpProblemDetailsConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | package org.springframework.hateoas.mediatype.problem;
2 |
3 | import java.util.Collection;
4 |
5 | import org.springframework.hateoas.MediaTypes;
6 | import org.springframework.hateoas.config.HypermediaMappingInformation;
7 | import org.springframework.hateoas.config.MediaTypeConfigurationProvider;
8 | import org.springframework.http.MediaType;
9 |
10 | /**
11 | * {@link MediaTypeConfigurationProvider} for HAL.
12 | *
13 | * @author Oliver Drotbohm
14 | */
15 | class HttpProblemDetailsConfigurationProvider implements MediaTypeConfigurationProvider {
16 |
17 | /*
18 | * (non-Javadoc)
19 | * @see org.springframework.hateoas.config.HyperMediaTypeProvider#getConfiguration()
20 | */
21 | @Override
22 | public Class extends HypermediaMappingInformation> getConfiguration() {
23 | return HttpProblemDetailsMappingInformation.class;
24 | }
25 |
26 | /*
27 | * (non-Javadoc)
28 | * @see org.springframework.hateoas.config.HyperMediaTypeProvider#supportsAny(java.util.Collection)
29 | */
30 | @Override
31 | public boolean supportsAny(Collection mediaTypes) {
32 | return mediaTypes.contains(MediaTypes.HTTP_PROBLEM_DETAILS_JSON);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/problem/HttpProblemDetailsMappingInformation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.problem;
17 |
18 | import java.util.Collections;
19 | import java.util.List;
20 |
21 | import org.springframework.hateoas.MediaTypes;
22 | import org.springframework.hateoas.config.HypermediaMappingInformation;
23 | import org.springframework.http.MediaType;
24 |
25 | /**
26 | * {@link HypermediaMappingInformation} implementation to setup support for {@link Problem}.
27 | *
28 | * @author Oliver Drotbohm
29 | */
30 | class HttpProblemDetailsMappingInformation implements HypermediaMappingInformation {
31 |
32 | /*
33 | * (non-Javadoc)
34 | * @see org.springframework.hateoas.config.HypermediaMappingInformation#getRootType()
35 | */
36 | @Override
37 | public Class> getRootType() {
38 | return Problem.class;
39 | }
40 |
41 | /*
42 | * (non-Javadoc)
43 | * @see org.springframework.hateoas.config.HypermediaMappingInformation#getMediaTypes()
44 | */
45 | @Override
46 | public List getMediaTypes() {
47 | return Collections.singletonList(MediaTypes.HTTP_PROBLEM_DETAILS_JSON);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/problem/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Value objects to build Problem representations.
3 | */
4 | @org.jspecify.annotations.NullMarked
5 | package org.springframework.hateoas.mediatype.problem;
6 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/uber/UberAffordanceModelFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.uber;
17 |
18 | import org.springframework.hateoas.AffordanceModel;
19 | import org.springframework.hateoas.MediaTypes;
20 | import org.springframework.hateoas.mediatype.AffordanceModelFactory;
21 | import org.springframework.hateoas.mediatype.ConfiguredAffordance;
22 | import org.springframework.http.MediaType;
23 |
24 | /**
25 | * {@link AffordanceModelFactory} for {@literal UBER+JSON}.
26 | *
27 | * @author Greg Turnquist
28 | * @author Oliver Drotbohm
29 | */
30 | class UberAffordanceModelFactory implements AffordanceModelFactory {
31 |
32 | /*
33 | * (non-Javadoc)
34 | * @see org.springframework.hateoas.mediatype.AffordanceModelFactory#getAffordanceModel(org.springframework.hateoas.mediatype.ConfiguredAffordance)
35 | */
36 | @Override
37 | public AffordanceModel getAffordanceModel(ConfiguredAffordance configured) {
38 | return new UberAffordanceModel(configured);
39 | }
40 |
41 | /*
42 | * (non-Javadoc)
43 | * @see org.springframework.hateoas.mediatype.AffordanceModelFactory#getMediaType()
44 | */
45 | @Override
46 | public MediaType getMediaType() {
47 | return MediaTypes.UBER_JSON;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/uber/UberMediaTypeConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.mediatype.uber;
17 |
18 | import java.util.Collection;
19 |
20 | import org.springframework.hateoas.MediaTypes;
21 | import org.springframework.hateoas.config.HypermediaMappingInformation;
22 | import org.springframework.hateoas.config.MediaTypeConfigurationProvider;
23 | import org.springframework.http.MediaType;
24 |
25 | /**
26 | * {@link MediaTypeConfigurationProvider} for Uber.
27 | *
28 | * @author Oliver Drotbohm
29 | */
30 | class UberMediaTypeConfigurationProvider implements MediaTypeConfigurationProvider {
31 |
32 | /*
33 | * (non-Javadoc)
34 | * @see org.springframework.hateoas.config.MediaTypeConfigurationProvider#getConfiguration()
35 | */
36 | @Override
37 | public Class extends HypermediaMappingInformation> getConfiguration() {
38 | return UberMediaTypeConfiguration.class;
39 | }
40 |
41 | /*
42 | * (non-Javadoc)
43 | * @see org.springframework.hateoas.config.MediaTypeConfigurationProvider#supportsAny(java.util.Collection)
44 | */
45 | @Override
46 | public boolean supportsAny(Collection mediaTypes) {
47 | return mediaTypes.contains(MediaTypes.UBER_JSON);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/mediatype/uber/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * UBER media type objects.
3 | */
4 | @org.jspecify.annotations.NullMarked
5 | package org.springframework.hateoas.mediatype.uber;
6 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Value objects to ease creating {@link org.springframework.hateoas.Link}s and link driven representations for REST
3 | * webservices.
4 | *
5 | * @author Oliver Drotbohm
6 | * @author Jens Schauder
7 | * @author Greg Turnquist
8 | */
9 | @org.jspecify.annotations.NullMarked
10 | package org.springframework.hateoas;
11 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/server/ExposesResourceFor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.server;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Inherited;
21 | import java.lang.annotation.Retention;
22 | import java.lang.annotation.RetentionPolicy;
23 | import java.lang.annotation.Target;
24 |
25 | /**
26 | * Annotation to demarcate controllers that expose URI templates of a structure according to
27 | * {@link ControllerEntityLinks}.
28 | *
29 | * @author Oliver Gierke
30 | */
31 | @Inherited
32 | @Documented
33 | @Retention(RetentionPolicy.RUNTIME)
34 | @Target(ElementType.TYPE)
35 | public @interface ExposesResourceFor {
36 |
37 | /**
38 | * The domain type the controller exposes resources for.
39 | *
40 | * @return
41 | */
42 | Class> value();
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/server/RepresentationModelProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.server;
17 |
18 | import org.springframework.hateoas.RepresentationModel;
19 |
20 | /**
21 | * SPI interface to allow components to process the {@link RepresentationModel} instances returned from Spring MVC
22 | * controllers.
23 | *
24 | * @see EntityModel
25 | * @see CollectionModel
26 | * @author Oliver Gierke
27 | */
28 | public interface RepresentationModelProcessor> {
29 |
30 | /**
31 | * Processes the given representation model, add links, alter the domain data etc.
32 | *
33 | * @param model
34 | * @return the processed model
35 | */
36 | T process(T model);
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/server/core/AbstractEntityLinks.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.server.core;
17 |
18 | import org.springframework.hateoas.server.EntityLinks;
19 | import org.springframework.hateoas.server.LinkBuilder;
20 |
21 | /**
22 | * Implementation base class to delegate the higher level methods of {@link EntityLinks} by delegating to the more fine
23 | * grained ones to reduce the implementation effort for actual implementation classes.
24 | *
25 | * @author Oliver Gierke
26 | */
27 | public abstract class AbstractEntityLinks implements EntityLinks {
28 |
29 | /*
30 | * (non-Javadoc)
31 | * @see org.springframework.hateoas.EntityLinks#linkForSingleResource(java.lang.Class, java.lang.Object)
32 | */
33 | @Override
34 | public LinkBuilder linkForItemResource(Class> type, Object id) {
35 | return linkFor(type).slash(id);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/server/core/EvoInflectorLinkRelationProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.server.core;
17 |
18 | import org.atteo.evo.inflector.English;
19 | import org.springframework.hateoas.LinkRelation;
20 |
21 | /**
22 | * {@link LinkRelationProvider} implementation using the Evo Inflector implementation of an algorithmic approach to
23 | * English plurals.
24 | *
25 | * @see http://users.monash.edu/~damian/papers/HTML/Plurals.html
26 | * @author Oliver Gierke
27 | */
28 | public class EvoInflectorLinkRelationProvider extends DefaultLinkRelationProvider {
29 |
30 | /*
31 | * (non-Javadoc)
32 | * @see org.springframework.hateoas.server.core.DefaultLinkRelationProvider#getCollectionResourceRelFor(java.lang.Class)
33 | */
34 | @Override
35 | public LinkRelation getCollectionResourceRelFor(Class> type) {
36 | return LinkRelation.of(English.plural(getItemResourceRelFor(type).value()));
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/hateoas/server/core/LastInvocationAware.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2024 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.hateoas.server.core;
17 |
18 | import java.util.Iterator;
19 |
20 | import org.jspecify.annotations.Nullable;
21 |
22 | /**
23 | * @author Oliver Drotbohm
24 | * @author Greg Turnquist
25 | */
26 | public interface LastInvocationAware {
27 |
28 | Iterator