Add Spring Mobile Device Resolver autoconfiguration
parent
f306eda703
commit
5cdaa43912
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.autoconfigure.mobile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.mobile.device.DeviceHandlerMethodArgumentResolver;
|
||||||
|
import org.springframework.mobile.device.DeviceResolver;
|
||||||
|
import org.springframework.mobile.device.DeviceResolverHandlerInterceptor;
|
||||||
|
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link EnableAutoConfiguration Auto-configuration} for Spring Mobile's
|
||||||
|
* {@link DeviceResolver}.
|
||||||
|
*
|
||||||
|
* @author Roy Clarkson
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnClass({ DeviceResolverHandlerInterceptor.class,
|
||||||
|
DeviceHandlerMethodArgumentResolver.class })
|
||||||
|
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
|
||||||
|
public class DeviceResolverAutoConfiguration {
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnWebApplication
|
||||||
|
protected static class DeviceResolverAutoConfigurationAdapter extends
|
||||||
|
WebMvcConfigurerAdapter {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(DeviceResolverHandlerInterceptor.class)
|
||||||
|
public DeviceResolverHandlerInterceptor deviceResolverHandlerInterceptor() {
|
||||||
|
return new DeviceResolverHandlerInterceptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DeviceHandlerMethodArgumentResolver deviceHandlerMethodArgumentResolver() {
|
||||||
|
return new DeviceHandlerMethodArgumentResolver();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
|
registry.addInterceptor(deviceResolverHandlerInterceptor());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addArgumentResolvers(
|
||||||
|
List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||||
|
argumentResolvers.add(deviceHandlerMethodArgumentResolver());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.autoconfigure.mobile;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
|
||||||
|
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
|
||||||
|
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor;
|
||||||
|
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
|
||||||
|
import org.springframework.boot.context.embedded.MockEmbeddedServletContainerFactory;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.mobile.device.DeviceHandlerMethodArgumentResolver;
|
||||||
|
import org.springframework.mobile.device.DeviceResolverHandlerInterceptor;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link DeviceResolverAutoConfiguration}.
|
||||||
|
*
|
||||||
|
* @author Roy Clarkson
|
||||||
|
*/
|
||||||
|
public class DeviceResolverAutoConfigurationTests {
|
||||||
|
|
||||||
|
private static final MockEmbeddedServletContainerFactory containerFactory = new MockEmbeddedServletContainerFactory();
|
||||||
|
|
||||||
|
private AnnotationConfigWebApplicationContext context;
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void close() {
|
||||||
|
if (this.context != null) {
|
||||||
|
this.context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deviceResolverHandlerInterceptorCreated() throws Exception {
|
||||||
|
this.context = new AnnotationConfigWebApplicationContext();
|
||||||
|
this.context.register(DeviceResolverAutoConfiguration.class);
|
||||||
|
this.context.refresh();
|
||||||
|
assertNotNull(this.context.getBean(DeviceResolverHandlerInterceptor.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deviceHandlerMethodArgumentResolverCreated() throws Exception {
|
||||||
|
this.context = new AnnotationConfigWebApplicationContext();
|
||||||
|
this.context.register(DeviceResolverAutoConfiguration.class);
|
||||||
|
this.context.refresh();
|
||||||
|
assertNotNull(this.context.getBean(DeviceHandlerMethodArgumentResolver.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void deviceResolverHandlerInterceptorRegistered() throws Exception {
|
||||||
|
AnnotationConfigEmbeddedWebApplicationContext context = new AnnotationConfigEmbeddedWebApplicationContext();
|
||||||
|
context.register(Config.class, WebMvcAutoConfiguration.class,
|
||||||
|
DeviceResolverAutoConfiguration.class);
|
||||||
|
context.refresh();
|
||||||
|
RequestMappingHandlerMapping mapping = (RequestMappingHandlerMapping) context
|
||||||
|
.getBean("requestMappingHandlerMapping");
|
||||||
|
Field interceptorsField = ReflectionUtils.findField(
|
||||||
|
RequestMappingHandlerMapping.class, "interceptors");
|
||||||
|
interceptorsField.setAccessible(true);
|
||||||
|
List<Object> interceptors = (List<Object>) ReflectionUtils.getField(
|
||||||
|
interceptorsField, mapping);
|
||||||
|
context.close();
|
||||||
|
for (Object o : interceptors) {
|
||||||
|
if (o instanceof DeviceResolverHandlerInterceptor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fail("DeviceResolverHandlerInterceptor was not registered.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
protected static class Config {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public EmbeddedServletContainerFactory containerFactory() {
|
||||||
|
return containerFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public EmbeddedServletContainerCustomizerBeanPostProcessor embeddedServletContainerCustomizerBeanPostProcessor() {
|
||||||
|
return new EmbeddedServletContainerCustomizerBeanPostProcessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package org.test
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@EnableDeviceResolver
|
||||||
|
class Example {
|
||||||
|
|
||||||
|
@RequestMapping("/")
|
||||||
|
@ResponseBody
|
||||||
|
public String helloWorld(Device device) {
|
||||||
|
if (device.isNormal()) {
|
||||||
|
return "Hello Normal Device!"
|
||||||
|
} else if (device.isMobile()) {
|
||||||
|
return "Hello Mobile Device!"
|
||||||
|
} else if (device.isTablet()) {
|
||||||
|
return "Hello Tablet Device!"
|
||||||
|
} else {
|
||||||
|
return "Hello Unknown Device!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.cli.compiler.autoconfigure;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.codehaus.groovy.ast.ClassNode;
|
||||||
|
import org.codehaus.groovy.control.CompilationFailedException;
|
||||||
|
import org.codehaus.groovy.control.customizers.ImportCustomizer;
|
||||||
|
import org.springframework.boot.cli.compiler.AstUtils;
|
||||||
|
import org.springframework.boot.cli.compiler.CompilerAutoConfiguration;
|
||||||
|
import org.springframework.boot.cli.compiler.DependencyCustomizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link CompilerAutoConfiguration} for Spring Mobile.
|
||||||
|
*
|
||||||
|
* @author Roy Clarkson
|
||||||
|
*/
|
||||||
|
public class SpringMobileCompilerAutoConfiguration extends CompilerAutoConfiguration {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(ClassNode classNode) {
|
||||||
|
return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableDeviceResolver");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyDependencies(DependencyCustomizer dependencies)
|
||||||
|
throws CompilationFailedException {
|
||||||
|
dependencies.add("org.springframework.mobile", "spring-mobile-device",
|
||||||
|
dependencies.getProperty("spring-mobile.version"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyImports(ImportCustomizer imports) throws CompilationFailedException {
|
||||||
|
imports.addStarImports("org.springframework.mobile.device");
|
||||||
|
imports.addImports(EnableDeviceResolver.class.getCanonicalName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Documented
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public static @interface EnableDeviceResolver {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue