Skip to content

Commit

Permalink
Add builder decorators to configure builders with defaults
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy Buttaro committed Sep 5, 2018
1 parent 331b349 commit d7123c2
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.github.restup.controller.content.negotiation;

import com.github.restup.controller.content.negotiation.ContentNegotiator.Builder;

@FunctionalInterface
public interface ContentNegotiatorBuilderDecorator {

/**
* Decorate a {@link Builder}. Useful in dependency injection frameworks such as Spring where a
* default builder can complete basic wiring requiring only customization to be configured.
*
* @param builder to decorate
* @return the builder
*/
Builder decorate(Builder builder);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.github.restup.controller.request.parser;


import com.github.restup.controller.request.parser.RequestParser.Builder;

@FunctionalInterface
public interface RequestParserBuilderDecorator {

/**
* Decorate a {@link Builder}. Useful in dependency injection frameworks such as Spring where a
* default builder can complete basic wiring requiring only customization to be configured.
*
* @param builder to decorate
* @return the builder
*/
Builder decorate(Builder builder);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.github.restup;

import com.github.restup.registry.ResourceRegistry.Builder;

@FunctionalInterface
public interface ResourceRegistryBuilderDecorator {

/**
* Decorate a {@link Builder}. Useful in dependency injection frameworks such as Spring where a
* default builder can complete basic wiring requiring only customization to be configured.
*
* @param builder to decorate
* @return the builder
*/
Builder decorate(Builder builder);

}
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
package com.github.restup.spring.boot.autoconfigure;

import java.util.List;
import java.util.Set;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.domain.EntityScanPackages;
import org.springframework.boot.autoconfigure.domain.EntityScanner;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.github.restup.ResourceRegistryBuilderDecorator;
import com.github.restup.annotations.ApiName;
import com.github.restup.annotations.Plural;
import com.github.restup.annotations.Resource;
Expand All @@ -30,6 +20,17 @@
import com.github.restup.spring.boot.autoconfigure.factory.RestrictedFieldsProviderFactory;
import com.github.restup.spring.boot.autoconfigure.factory.ServiceFilterFactory;
import com.github.restup.spring.boot.autoconfigure.factory.SparseFieldsProviderFactory;
import java.util.List;
import java.util.Set;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.domain.EntityScanPackages;
import org.springframework.boot.autoconfigure.domain.EntityScanner;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConditionalOnClass(ResourceRegistry.class)
Expand All @@ -45,6 +46,20 @@ public UpAutoConfiguration(UpProperties props, ApplicationContext applicationCon
this.applicationContext = applicationContext;
}

static Set<Class<?>> getResources(ApplicationContext applicationContext)
throws ClassNotFoundException {
return new EntityScanner(applicationContext)
.scan(Resource.class, ApiName.class, Plural.class);
}

static List<String> getPackages(ApplicationContext applicationContext) {
List<String> packages = EntityScanPackages.get(applicationContext).getPackageNames();
if (packages.isEmpty() && AutoConfigurationPackages.has(applicationContext)) {
packages = AutoConfigurationPackages.get(applicationContext);
}
return packages;
}

@Bean
@ConditionalOnMissingBean
public ControllerMethodAccess defaultUpControllerMethodAccess() {
Expand Down Expand Up @@ -85,7 +100,8 @@ public Pagination defaultUpPagination() {
public MappedClassFactory defaultUpMappedClassFactory() {
MappedFieldBuilderVisitor[] visitors = MappedFieldBuilderVisitor.getDefaultVisitors();
DefaultMappedFieldFactory mappedFieldFactory = new DefaultMappedFieldFactory(visitors);
return new DefaultMappedClassFactory(mappedFieldFactory, getPackages(this.applicationContext), MappedClass.getDefaultFieldComparator());
return new DefaultMappedClassFactory(mappedFieldFactory, getPackages(applicationContext),
MappedClass.getDefaultFieldComparator());
}

@Bean
Expand All @@ -112,25 +128,32 @@ public SparseFieldsProviderFactory defaultUpSparseFieldsProviderFactory() {
return new SparseFieldsProviderFactory() {};
}

@Bean
@ConditionalOnMissingBean
public ResourceRegistryBuilderDecorator defaultUpResourceRegistryBuilderDecorator() {
return (b) -> b;
}

@Bean
@ConditionalOnMissingBean
public ResourceRegistry defaultUpRegistry(
ControllerMethodAccess controllerMethodAccess,
ConverterFactory converterFactory,
ErrorFactory errorFactory,
MappedClassFactory mappedClassFactory,
Pagination pagination,
RepositoryFactory repositoryFactory,
RequestObjectFactory requestObjectFactory,
ServiceMethodAccess serviceMethodAccess,
ServiceFilterFactory serviceFilterFactory,
RestrictedFieldsProviderFactory restrictedFieldsProviderFactory,
SparseFieldsProviderFactory sparseFieldsProviderFactory) throws ClassNotFoundException {

return ResourceRegistry.builder()
ControllerMethodAccess controllerMethodAccess,
ConverterFactory converterFactory,
ErrorFactory errorFactory,
MappedClassFactory mappedClassFactory,
Pagination pagination,
RepositoryFactory repositoryFactory,
RequestObjectFactory requestObjectFactory,
ServiceMethodAccess serviceMethodAccess,
ServiceFilterFactory serviceFilterFactory,
RestrictedFieldsProviderFactory restrictedFieldsProviderFactory,
SparseFieldsProviderFactory sparseFieldsProviderFactory,
ResourceRegistryBuilderDecorator decorator) throws ClassNotFoundException {

return decorator.decorate(
ResourceRegistry.builder()
.basePath(props.getBasePath())
.excludeFrameworkFilters(props.isExcludeFrameworkFilters())
.packagesToScan("com.foo", "com.bar")
.controllerMethodAccess(controllerMethodAccess)
.defaultPagination(pagination)
.errorFactory(errorFactory)
Expand All @@ -142,20 +165,7 @@ public ResourceRegistry defaultUpRegistry(
.defaultServiceFilters(serviceFilterFactory.getServiceFilters())
.defaultRestrictedFieldsProvider(restrictedFieldsProviderFactory.getRestrictedFieldsProvider())
.defaultSparseFieldsProvider(sparseFieldsProviderFactory.getSparseFieldsProvider())
.build();
}

static Set<Class<?>> getResources(ApplicationContext applicationContext) throws ClassNotFoundException {
return new EntityScanner(applicationContext)
.scan(Resource.class, ApiName.class, Plural.class);
}

static List<String> getPackages(ApplicationContext applicationContext) {
List<String> packages = EntityScanPackages.get(applicationContext).getPackageNames();
if (packages.isEmpty() && AutoConfigurationPackages.has(applicationContext)) {
packages = AutoConfigurationPackages.get(applicationContext);
}
return packages;
).build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import com.github.restup.controller.ExceptionHandler;
import com.github.restup.controller.ResourceController;
import com.github.restup.controller.content.negotiation.ContentNegotiator;
import com.github.restup.controller.content.negotiation.ContentNegotiatorBuilderDecorator;
import com.github.restup.controller.linking.LinkBuilderFactory;
import com.github.restup.controller.linking.discovery.CachedServiceDiscovery;
import com.github.restup.controller.linking.discovery.ServiceDiscovery;
import com.github.restup.controller.request.parser.RequestParser;
import com.github.restup.controller.request.parser.RequestParserBuilderDecorator;
import com.github.restup.registry.ResourceRegistry;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
Expand Down Expand Up @@ -63,8 +65,22 @@ public ResourceControllerBuilderDecorator defaultUpResourceControllerBuilderDeco

@Bean
@ConditionalOnMissingBean
public RequestParser defaultUpRequestParser(ObjectMapper mapper) {
return RequestParser.builder()
public RequestParserBuilderDecorator defaultUpRequestParserBuilderDecorator() {
return (b) -> b;
}

@Bean
@ConditionalOnMissingBean
public ContentNegotiatorBuilderDecorator defaultUpContentNegotiatorBuilderDecorator() {
return (b) -> b;
}

@Bean
@ConditionalOnMissingBean
public RequestParser defaultUpRequestParser(ObjectMapper mapper,
RequestParserBuilderDecorator decorator) {
return decorator.decorate(
RequestParser.builder()
.autoDetectDisabled(props.isDisableSerializationAutoDetection())
.defaultMediaType(props.getDefaultMediaType())
.fieldsParamName(props.getFieldsParamName())
Expand All @@ -75,19 +91,20 @@ public RequestParser defaultUpRequestParser(ObjectMapper mapper) {
.pageOffsetParamName(props.getOffsetParamName())
.sortParamName(props.getSortParamName())
.jacksonObjectMapper(mapper)
.build();
).build();
}

@Bean
@ConditionalOnMissingBean
public ContentNegotiator defaultUpContentNegotiator(ServiceDiscovery serviceDiscovery,
LinkBuilderFactory linkBuilderFactory) {
return ContentNegotiator.builder()
LinkBuilderFactory linkBuilderFactory, ContentNegotiatorBuilderDecorator decorator) {
return decorator.decorate(
ContentNegotiator.builder()
.autoDetectDisabled(props.isDisableSerializationAutoDetection())
.defaultMediaType(props.getDefaultMediaType())
.serviceDiscovery(serviceDiscovery)
.linkBuilderFactory(linkBuilderFactory)
.build();
).build();
}

@Bean
Expand All @@ -99,7 +116,8 @@ public ResourceController defaultUpResourceController(ResourceRegistry registry,
RequestParser requestParser,
ResourceControllerBuilderDecorator decorator,
ContentNegotiator contentNegotiator) {
return decorator.decorate(ResourceController.builder()
return decorator.decorate(
ResourceController.builder()
.registry(registry)
.serviceDiscovery(serviceDiscovery)
.linkBuilderFactory(linkBuilderFactory)
Expand Down

0 comments on commit d7123c2

Please sign in to comment.