Commit c34cfb27 authored by Phillip Webb's avatar Phillip Webb

Polish

parent b53d72e9
......@@ -17,6 +17,7 @@
package org.springframework.boot.actuate.endpoint;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
......@@ -286,6 +287,9 @@ public class ConfigurationPropertiesReportEndpoint extends
}
/**
* {@link BeanSerializerModifier} to return only relevant configuration properties.
*/
protected static class GenericSerializerModifier extends BeanSerializerModifier {
@Override
......@@ -302,7 +306,7 @@ public class ConfigurationPropertiesReportEndpoint extends
}
private boolean isReadable(BeanDescription beanDesc, BeanPropertyWriter writer) {
String parenType = beanDesc.getType().getRawClass().getName();
String parentType = beanDesc.getType().getRawClass().getName();
String type = writer.getPropertyType().getName();
AnnotatedMethod setter = beanDesc.findMethod(
"set" + StringUtils.capitalize(writer.getName()),
......@@ -312,10 +316,9 @@ public class ConfigurationPropertiesReportEndpoint extends
// that its a nested class used solely for binding to config props, so it
// should be kosher. This filter is not used if there is JSON metadata for
// the property, so it's mainly for user-defined beans.
boolean readable = setter != null
|| ClassUtils.getPackageName(parenType).equals(
return (setter != null)
|| ClassUtils.getPackageName(parentType).equals(
ClassUtils.getPackageName(type));
return readable;
}
}
......@@ -327,9 +330,11 @@ public class ConfigurationPropertiesReportEndpoint extends
*/
protected static class ConfigurationPropertiesMetaData {
private Map<String, Set<String>> matched = new HashMap<String, Set<String>>();
private final String metadataLocations;
private final Map<String, Set<String>> matched = new HashMap<String, Set<String>>();
private Set<String> keys = null;
private String metadataLocations;
public ConfigurationPropertiesMetaData(String metadataLocations) {
this.metadataLocations = metadataLocations;
......@@ -349,53 +354,45 @@ public class ConfigurationPropertiesReportEndpoint extends
}
private boolean matchesInternal(String prefix) {
if (this.matched.get(prefix) != null) {
return true;
}
else {
return false;
}
return this.matched.get(prefix) != null;
}
private Set<String> findKeys(String prefix) {
HashSet<String> set = new HashSet<String>();
try {
if (this.keys == null) {
this.keys = new HashSet<String>();
ObjectMapper mapper = new ObjectMapper();
Resource[] resources = new PathMatchingResourcePatternResolver()
.getResources(this.metadataLocations);
for (Resource resource : resources) {
addKeys(mapper, resource);
}
}
}
catch (IOException e) {
logger.warn("Could not deserialize config properties metadata", e);
}
for (String key : this.keys) {
HashSet<String> keys = new HashSet<String>();
for (String key : getKeys()) {
if (key.length() > prefix.length()
&& key.startsWith(prefix)
&& ".".equals(key.substring(prefix.length(), prefix.length() + 1))) {
set.add(key.substring(prefix.length() + 1));
keys.add(key.substring(prefix.length() + 1));
}
}
return (keys.isEmpty() ? null : keys);
}
private Set<String> getKeys() {
if (this.keys != null) {
return this.keys;
}
this.keys = new HashSet<String>();
try {
ObjectMapper mapper = new ObjectMapper();
Resource[] resources = new PathMatchingResourcePatternResolver()
.getResources(this.metadataLocations);
for (Resource resource : resources) {
addKeys(mapper, resource);
}
}
if (set.isEmpty()) {
return null;
catch (IOException ex) {
logger.warn("Could not deserialize config properties metadata", ex);
}
return set;
return this.keys;
}
@SuppressWarnings("unchecked")
private void addKeys(ObjectMapper mapper, Resource resource) throws IOException,
JsonParseException, JsonMappingException {
@SuppressWarnings("unchecked")
Map<String, Object> map = mapper.readValue(resource.getInputStream(),
Map.class);
@SuppressWarnings("unchecked")
InputStream inputStream = resource.getInputStream();
Map<String, Object> map = mapper.readValue(inputStream, Map.class);
Collection<Map<String, Object>> metadata = (Collection<Map<String, Object>>) map
.get("properties");
for (Map<String, Object> value : metadata) {
......@@ -404,8 +401,8 @@ public class ConfigurationPropertiesReportEndpoint extends
this.keys.add((String) value.get("name"));
}
}
catch (Exception e) {
logger.warn("Could not parse config properties metadata", e);
catch (Exception ex) {
logger.warn("Could not parse config properties metadata", ex);
}
}
}
......@@ -421,13 +418,13 @@ public class ConfigurationPropertiesReportEndpoint extends
return map;
}
@SuppressWarnings("unchecked")
private void addProperty(Object bean, String key, Map<String, Object> map) {
String prefix = key.contains(".") ? StringUtils.split(key, ".")[0] : key;
String suffix = key.length() > prefix.length() ? key.substring(prefix
.length() + 1) : null;
String prefix = (key.contains(".") ? StringUtils.split(key, ".")[0] : key);
String suffix = (key.length() > prefix.length() ? key.substring(prefix
.length() + 1) : null);
String property = prefix;
if (bean instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> value = (Map<String, Object>) bean;
bean = new MapHolder(value);
property = "map[" + property + "]";
......@@ -446,14 +443,15 @@ public class ConfigurationPropertiesReportEndpoint extends
map.put(prefix, value);
}
}
catch (Exception e) {
catch (Exception ex) {
// Probably just lives on a different bean (it happens)
logger.debug("Could not parse config properties metadata '" + key + "': "
+ e.getMessage());
+ ex.getMessage());
}
}
protected static class MapHolder {
Map<String, Object> map = new HashMap<String, Object>();
public MapHolder(Map<String, Object> bean) {
......@@ -467,6 +465,7 @@ public class ConfigurationPropertiesReportEndpoint extends
public void setMap(Map<String, Object> map) {
this.map = map;
}
}
}
......
......@@ -20,9 +20,14 @@ package org.springframework.boot.actuate.endpoint.mvc;
* Callback for customizing the {@link EndpointHandlerMapping} at configuration time.
*
* @author Dave Syer
* @since 1.2.0
*/
public interface EndpointHandlerMappingCustomizer {
/**
* Customize the specified {@link EndpointHandlerMapping}
* @param mapping the {@link EndpointHandlerMapping} to customize
*/
void customize(EndpointHandlerMapping mapping);
}
......@@ -97,6 +97,7 @@ public class EndpointMvcIntegrationTests {
HttpMessageConvertersAutoConfiguration.class,
ErrorMvcAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
protected static @interface MinimalWebConfiguration {
}
@Configuration
......@@ -134,9 +135,11 @@ public class EndpointMvcIntegrationTests {
protected TestInterceptor interceptor() {
return new TestInterceptor();
}
}
protected static class TestInterceptor extends HandlerInterceptorAdapter {
private int count = 0;
@Override
......@@ -148,6 +151,7 @@ public class EndpointMvcIntegrationTests {
public int getCount() {
return this.count;
}
}
}
......@@ -471,6 +471,7 @@ public class EndpointWebMvcAutoConfigurationTests {
public EmbeddedServletContainer getServletContainer() {
return this.servletContainer;
}
}
}
......@@ -36,8 +36,8 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
......@@ -98,7 +98,7 @@ public class JerseyAutoConfiguration implements WebApplicationInitializer {
@Bean
@ConditionalOnMissingBean(name = "jerseyFilterRegistration")
@ConditionalOnExpression("'${spring.jersey.type:servlet}' == 'filter'")
@ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "filter")
public FilterRegistrationBean jerseyFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new ServletContainer());
......@@ -121,7 +121,7 @@ public class JerseyAutoConfiguration implements WebApplicationInitializer {
@Bean
@ConditionalOnMissingBean(name = "jerseyServletRegistration")
@ConditionalOnExpression("'${spring.jersey.type:servlet}' == 'servlet'")
@ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "servlet", matchIfMissing = true)
public ServletRegistrationBean jerseyServletRegistration() {
ServletRegistrationBean registration = new ServletRegistrationBean(
new ServletContainer(), this.path);
......
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.jersey;
import java.util.HashMap;
......@@ -21,17 +22,15 @@ import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author Dave Syer
* {@link ConfigurationProperties} for Jersey.
*
* @author Dave Syer
* @since 1.2.0
*/
@ConfigurationProperties("spring.jersey")
public class JerseyProperties {
public enum Type {
servlet, filter;
}
private Type type = Type.servlet;
private Type type = Type.SERVLET;
private Map<String, String> init = new HashMap<String, String>();
......@@ -61,6 +60,10 @@ public class JerseyProperties {
this.init = init;
}
public enum Type {
SERVLET, FILTER;
}
public static class Filter {
private int order;
......
......@@ -46,8 +46,8 @@ import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.util.StringUtils;
/**
* {@link ConfigurationProperties properties} for a web server (e.g. port and path
* settings). Will be used to customize an {@link EmbeddedServletContainerFactory} when an
* {@link ConfigurationProperties} for a web server (e.g. port and path settings). Will be
* used to customize an {@link EmbeddedServletContainerFactory} when an
* {@link EmbeddedServletContainerCustomizerBeanPostProcessor} is active.
*
* @author Dave Syer
......
/*
* Copyright 2012-2014 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.websocket;
import org.eclipse.jetty.webapp.AbstractConfiguration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
/**
* {@link WebSocketContainerCustomizer} for {@link JettyEmbeddedServletContainerFactory}.
*
* @author Dave Syer
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.2.0
*/
public class JettyWebSocketContainerCustomizer extends
WebSocketContainerCustomizer<JettyEmbeddedServletContainerFactory> {
@Override
protected void doCustomize(JettyEmbeddedServletContainerFactory container) {
container.addConfigurations(new AbstractConfiguration() {
@Override
public void configure(WebAppContext context) throws Exception {
WebSocketServerContainerInitializer.configureContext(context);
}
});
}
}
/*
* Copyright 2012-2014 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.websocket;
import java.lang.reflect.Constructor;
import org.apache.catalina.Context;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
* {@link WebSocketContainerCustomizer} for {@link TomcatEmbeddedServletContainerFactory}.
*
* @author Dave Syer
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.2.0
*/
public class TomcatWebSocketContainerCustomizer extends
WebSocketContainerCustomizer<TomcatEmbeddedServletContainerFactory> {
private static final String TOMCAT_7_LISTENER_TYPE = "org.apache.catalina.deploy.ApplicationListener";
private static final String TOMCAT_8_LISTENER_TYPE = "org.apache.tomcat.util.descriptor.web.ApplicationListener";
private static final String WS_LISTENER = "org.apache.tomcat.websocket.server.WsContextListener";
@Override
public void doCustomize(TomcatEmbeddedServletContainerFactory tomcatContainer) {
tomcatContainer.addContextCustomizers(new TomcatContextCustomizer() {
@Override
public void customize(Context context) {
addListener(context, findListenerType());
}
});
}
private Class<?> findListenerType() {
if (ClassUtils.isPresent(TOMCAT_7_LISTENER_TYPE, null)) {
return ClassUtils.resolveClassName(TOMCAT_7_LISTENER_TYPE, null);
}
if (ClassUtils.isPresent(TOMCAT_8_LISTENER_TYPE, null)) {
return ClassUtils.resolveClassName(TOMCAT_8_LISTENER_TYPE, null);
}
// With Tomcat 8.0.8 ApplicationListener is not required
return null;
}
/**
* Instead of registering the WsSci directly as a ServletContainerInitializer, we use
* the ApplicationListener provided by Tomcat. Unfortunately the ApplicationListener
* class moved packages in Tomcat 8 and been deleted in 8.0.8 so we have to use
* reflection.
* @param context the current context
* @param listenerType the type of listener to add
*/
private void addListener(Context context, Class<?> listenerType) {
Class<? extends Context> contextClass = context.getClass();
if (listenerType == null) {
ReflectionUtils.invokeMethod(ClassUtils.getMethod(contextClass,
"addApplicationListener", String.class), context, WS_LISTENER);
}
else {
Constructor<?> constructor = ClassUtils.getConstructorIfAvailable(
listenerType, String.class, boolean.class);
Object instance = BeanUtils.instantiateClass(constructor, WS_LISTENER, false);
ReflectionUtils.invokeMethod(ClassUtils.getMethod(contextClass,
"addApplicationListener", listenerType), context, instance);
}
}
}
......@@ -18,39 +18,26 @@ package org.springframework.boot.autoconfigure.websocket;
import javax.servlet.Servlet;
import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jetty.webapp.AbstractConfiguration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.web.NonEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.socket.WebSocketHandler;
/**
* Auto configuration for websocket server in embedded Tomcat or Jetty. Requires
* <code>spring-websocket</code> and either Tomcat or Jetty with their WebSocket modules
* to be on the classpath.
* <p/>
* <p>
* If Tomcat's WebSocket support is detected on the classpath we add a listener that
* installs the Tomcat Websocket initializer. In a non-embedded container it should
* already be there.
* <p/>
* <p>
* If Jetty's WebSocket support is detected on the classpath we add a configuration that
* configures the context with WebSocket support. In a non-embedded container it should
* already be there.
......@@ -68,65 +55,12 @@ public class WebSocketAutoConfiguration {
@ConditionalOnClass(name = "org.apache.tomcat.websocket.server.WsSci", value = Tomcat.class)
static class TomcatWebSocketConfiguration {
private static final String TOMCAT_7_LISTENER_TYPE = "org.apache.catalina.deploy.ApplicationListener";
private static final String TOMCAT_8_LISTENER_TYPE = "org.apache.tomcat.util.descriptor.web.ApplicationListener";
private static final String WS_LISTENER = "org.apache.tomcat.websocket.server.WsContextListener";
@Bean
@ConditionalOnMissingBean(name = "websocketContainerCustomizer")
public EmbeddedServletContainerCustomizer websocketContainerCustomizer() {
return new WebSocketContainerCustomizer<TomcatEmbeddedServletContainerFactory>(
TomcatEmbeddedServletContainerFactory.class) {
@Override
public void doCustomize(
TomcatEmbeddedServletContainerFactory tomcatContainer) {
tomcatContainer.addContextCustomizers(new TomcatContextCustomizer() {
@Override
public void customize(Context context) {
addListener(context, findListenerType());
}
});
}
};
}
private static Class<?> findListenerType() {
if (ClassUtils.isPresent(TOMCAT_7_LISTENER_TYPE, null)) {
return ClassUtils.resolveClassName(TOMCAT_7_LISTENER_TYPE, null);
}
if (ClassUtils.isPresent(TOMCAT_8_LISTENER_TYPE, null)) {
return ClassUtils.resolveClassName(TOMCAT_8_LISTENER_TYPE, null);
}
// With Tomcat 8.0.8 ApplicationListener is not required
return null;
return new TomcatWebSocketContainerCustomizer();
}
/**
* Instead of registering the WsSci directly as a ServletContainerInitializer, we
* use the ApplicationListener provided by Tomcat. Unfortunately the
* ApplicationListener class moved packages in Tomcat 8 and been deleted in 8.0.8
* so we have to use reflection.
* @param context the current context
* @param listenerType the type of listener to add
*/
private static void addListener(Context context, Class<?> listenerType) {
if (listenerType == null) {
ReflectionUtils.invokeMethod(ClassUtils.getMethod(context.getClass(),
"addApplicationListener", String.class), context, WS_LISTENER);
}
else {
Object instance = BeanUtils.instantiateClass(ClassUtils
.getConstructorIfAvailable(listenerType, String.class,
boolean.class), WS_LISTENER, false);
ReflectionUtils.invokeMethod(ClassUtils.getMethod(context.getClass(),
"addApplicationListener", listenerType), context, instance);
}
}
}
@Configuration
......@@ -136,53 +70,9 @@ public class WebSocketAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "websocketContainerCustomizer")
public EmbeddedServletContainerCustomizer websocketContainerCustomizer() {
return new WebSocketContainerCustomizer<JettyEmbeddedServletContainerFactory>(
JettyEmbeddedServletContainerFactory.class) {
@Override
protected void doCustomize(JettyEmbeddedServletContainerFactory container) {
container.addConfigurations(new AbstractConfiguration() {
@Override
public void configure(WebAppContext context) throws Exception {
WebSocketServerContainerInitializer.configureContext(context);
}
});
}
};
return new JettyWebSocketContainerCustomizer();
}
}
abstract static class WebSocketContainerCustomizer<T extends ConfigurableEmbeddedServletContainer>
implements EmbeddedServletContainerCustomizer {
private Log logger = LogFactory.getLog(getClass());
private final Class<T> containerType;
protected WebSocketContainerCustomizer(Class<T> containerType) {
this.containerType = containerType;
}
@SuppressWarnings("unchecked")
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
if (container instanceof NonEmbeddedServletContainerFactory) {
this.logger
.info("NonEmbeddedServletContainerFactory detected. Websockets "
+ "support should be native so this normally is not a problem.");
return;
}
if (this.containerType.isAssignableFrom(container.getClass())) {
doCustomize((T) container);
}
}
protected abstract void doCustomize(T container);
}
}
/*
* Copyright 2012-2014 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.websocket;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.web.NonEmbeddedServletContainerFactory;
import org.springframework.core.ResolvableType;
/**
* {@link EmbeddedServletContainerCustomizer} to configure websockets for a given
* {@link EmbeddedServletContainerFactory}.
*
* @author Dave Syer
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.2.0
*/
public abstract class WebSocketContainerCustomizer<T extends EmbeddedServletContainerFactory>
implements EmbeddedServletContainerCustomizer {
private Log logger = LogFactory.getLog(getClass());
@SuppressWarnings("unchecked")
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
if (container instanceof NonEmbeddedServletContainerFactory) {
this.logger.info("NonEmbeddedServletContainerFactory "
+ "detected. Websockets support should be native so this "
+ "normally is not a problem.");
return;
}
if (getContainerType().isAssignableFrom(container.getClass())) {
doCustomize((T) container);
}
}
protected Class<?> getContainerType() {
return ResolvableType.forClass(WebSocketContainerCustomizer.class, getClass())
.resolveGeneric();
}
protected abstract void doCustomize(T container);
}
......@@ -134,7 +134,8 @@ class InitializrService {
*/
private CloseableHttpResponse executeInitializrMetadataRetrieval(String url) {
HttpGet request = new HttpGet(url);
request.setHeader(new BasicHeader(HttpHeaders.ACCEPT, "application/vnd.initializr.v2+json"));
request.setHeader(new BasicHeader(HttpHeaders.ACCEPT,
"application/vnd.initializr.v2+json"));
return execute(request, url, "retrieve metadata");
}
......
......@@ -138,7 +138,8 @@ class InitializrServiceMetadata {
}
JSONObject type = root.getJSONObject(TYPE_EL);
JSONArray array = type.getJSONArray(VALUES_EL);
String defaultType = type.has(DEFAULT_ATTRIBUTE) ? type.getString(DEFAULT_ATTRIBUTE) : null;
String defaultType = type.has(DEFAULT_ATTRIBUTE) ? type
.getString(DEFAULT_ATTRIBUTE) : null;
for (int i = 0; i < array.length(); i++) {
JSONObject typeJson = array.getJSONObject(i);
ProjectType projectType = parseType(typeJson, defaultType);
......
......@@ -25,7 +25,6 @@ import java.util.List;
import java.util.Map;
import org.apache.http.client.utils.URIBuilder;
import org.springframework.util.StringUtils;
/**
......@@ -209,7 +208,8 @@ class ProjectGenerationRequest {
}
if (!this.dependencies.isEmpty()) {
builder.setParameter("dependencies", StringUtils.collectionToCommaDelimitedString(this.dependencies));
builder.setParameter("dependencies",
StringUtils.collectionToCommaDelimitedString(this.dependencies));
}
if (this.javaVersion != null) {
builder.setParameter("javaVersion", this.javaVersion);
......
......@@ -43,7 +43,8 @@ public class InitializrServiceMetadataTests {
assertEquals("1.7", metadata.getDefaults().get("javaVersion"));
assertEquals("org.test", metadata.getDefaults().get("groupId"));
assertEquals("demo", metadata.getDefaults().get("name"));
assertEquals("Demo project for Spring Boot", metadata.getDefaults().get("description"));
assertEquals("Demo project for Spring Boot",
metadata.getDefaults().get("description"));
assertEquals("jar", metadata.getDefaults().get("packaging"));
assertEquals("java", metadata.getDefaults().get("language"));
assertEquals("demo", metadata.getDefaults().get("artifactId"));
......
......@@ -108,7 +108,8 @@ public class ProjectGenerationRequestTests {
this.request.setType("custom");
this.request.getDependencies().add("data-rest");
assertEquals(new URI(ProjectGenerationRequest.DEFAULT_SERVICE_URL
+ "/foo?dependencies=data-rest&type=custom"), this.request.generateUrl(metadata));
+ "/foo?dependencies=data-rest&type=custom"),
this.request.generateUrl(metadata));
}
@Test
......
{
"_links": {
"maven-build": {
"href": "http://localhost:8080/pom.xml?{dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"maven-project": {
"href": "http://localhost:8080/starter.zip{?dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-build": {
"href": "http://localhost:8080/build.gradle{?dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-project": {
"href": "http://localhost:8080/starter.zip{?dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
}
},
"dependencies": {
"type": "hierarchical-multi-select",
"values": [
{
"name": "Core",
"values": [
{
"name": "Security",
"id": "security",
"description": "Security description"
},
{
"name": "AOP",
"id": "aop"
}
]
},
{
"name": "Data",
"values": [
{
"name": "JDBC",
"id": "jdbc"
},
{
"name": "JPA",
"id": "data-jpa"
},
{
"name": "MongoDB",
"id": "data-mongodb"
}
]
}
]
},
"type": {
"type": "action",
"default": "maven-project",
"values": [
{
"id": "maven-build",
"name": "Maven POM",
"action": "/pom.xml",
"tags": {
"build": "maven",
"format": "build"
}
},
{
"id": "maven-project",
"name": "Maven Project",
"action": "/starter.zip",
"tags": {
"build": "maven",
"format": "project"
}
},
{
"id": "gradle-build",
"name": "Gradle Config",
"action": "/build.gradle",
"tags": {
"build": "gradle",
"format": "build"
}
},
{
"id": "gradle-project",
"name": "Gradle Project",
"action": "/starter.zip",
"tags": {
"build": "gradle",
"format": "project"
}
}
]
},
"packaging": {
"type": "single-select",
"default": "jar",
"values": [
{
"id": "jar",
"name": "Jar"
},
{
"id": "war",
"name": "War"
}
]
},
"javaVersion": {
"type": "single-select",
"default": "1.7",
"values": [
{
"id": "1.6",
"name": "1.6"
},
{
"id": "1.7",
"name": "1.7"
},
{
"id": "1.8",
"name": "1.8"
}
]
},
"language": {
"type": "single-select",
"default": "java",
"values": [
{
"id": "groovy",
"name": "Groovy"
},
{
"id": "java",
"name": "Java"
}
]
},
"bootVersion": {
"type": "single-select",
"default": "1.1.8.RELEASE",
"values": [
{
"id": "1.2.0.BUILD-SNAPSHOT",
"name": "1.2.0 (SNAPSHOT)"
},
{
"id": "1.1.8.RELEASE",
"name": "1.1.8"
},
{
"id": "1.1.8.BUILD-SNAPSHOT",
"name": "1.1.8 (SNAPSHOT)"
},
{
"id": "1.0.2.RELEASE",
"name": "1.0.2"
}
]
},
"groupId": {
"type": "text",
"default": "org.test"
},
"artifactId": {
"type": "text",
"default": "demo"
},
"version": {
"type": "text",
"default": "0.0.1-SNAPSHOT"
},
"name": {
"type": "text",
"default": "demo"
},
"description": {
"type": "text",
"default": "Demo project for Spring Boot"
},
"packageName": {
"type": "text",
"default": "demo"
}
}
\ No newline at end of file
"_links": {
"maven-build": {
"href": "http://localhost:8080/pom.xml?{dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"maven-project": {
"href": "http://localhost:8080/starter.zip{?dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-build": {
"href": "http://localhost:8080/build.gradle{?dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-project": {
"href": "http://localhost:8080/starter.zip{?dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
}
},
"dependencies": {
"type": "hierarchical-multi-select",
"values": [
{
"name": "Core",
"values": [
{
"name": "Security",
"id": "security",
"description": "Security description"
},
{
"name": "AOP",
"id": "aop"
}
]
},
{
"name": "Data",
"values": [
{
"name": "JDBC",
"id": "jdbc"
},
{
"name": "JPA",
"id": "data-jpa"
},
{
"name": "MongoDB",
"id": "data-mongodb"
}
]
}
]
},
"type": {
"type": "action",
"default": "maven-project",
"values": [
{
"id": "maven-build",
"name": "Maven POM",
"action": "/pom.xml",
"tags": {
"build": "maven",
"format": "build"
}
},
{
"id": "maven-project",
"name": "Maven Project",
"action": "/starter.zip",
"tags": {
"build": "maven",
"format": "project"
}
},
{
"id": "gradle-build",
"name": "Gradle Config",
"action": "/build.gradle",
"tags": {
"build": "gradle",
"format": "build"
}
},
{
"id": "gradle-project",
"name": "Gradle Project",
"action": "/starter.zip",
"tags": {
"build": "gradle",
"format": "project"
}
}
]
},
"packaging": {
"type": "single-select",
"default": "jar",
"values": [
{
"id": "jar",
"name": "Jar"
},
{
"id": "war",
"name": "War"
}
]
},
"javaVersion": {
"type": "single-select",
"default": "1.7",
"values": [
{
"id": "1.6",
"name": "1.6"
},
{
"id": "1.7",
"name": "1.7"
},
{
"id": "1.8",
"name": "1.8"
}
]
},
"language": {
"type": "single-select",
"default": "java",
"values": [
{
"id": "groovy",
"name": "Groovy"
},
{
"id": "java",
"name": "Java"
}
]
},
"bootVersion": {
"type": "single-select",
"default": "1.1.8.RELEASE",
"values": [
{
"id": "1.2.0.BUILD-SNAPSHOT",
"name": "1.2.0 (SNAPSHOT)"
},
{
"id": "1.1.8.RELEASE",
"name": "1.1.8"
},
{
"id": "1.1.8.BUILD-SNAPSHOT",
"name": "1.1.8 (SNAPSHOT)"
},
{
"id": "1.0.2.RELEASE",
"name": "1.0.2"
}
]
},
"groupId": {
"type": "text",
"default": "org.test"
},
"artifactId": {
"type": "text",
"default": "demo"
},
"version": {
"type": "text",
"default": "0.0.1-SNAPSHOT"
},
"name": {
"type": "text",
"default": "demo"
},
"description": {
"type": "text",
"default": "Demo project for Spring Boot"
},
"packageName": {
"type": "text",
"default": "demo"
}
}
{
"_links": {
"maven-build": {
"href": "http://localhost:8080/pom.xml?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"maven-project": {
"href": "http://localhost:8080/starter.zip?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-build": {
"href": "http://localhost:8080/build.gradle?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-project": {
"href": "http://localhost:8080/starter.zip?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
}
},
"dependencies": {
"type": "hierarchical-multi-select",
"values": [
{
"name": "Core",
"values": [
{
"name": "Security",
"id": "security",
"description": "Security description"
},
{
"name": "AOP",
"id": "aop"
}
]
},
{
"name": "Data",
"values": [
{
"name": "JDBC",
"id": "jdbc"
},
{
"name": "JPA",
"id": "data-jpa"
},
{
"name": "MongoDB",
"id": "data-mongodb"
}
]
}
]
},
"type": {
"type": "action",
"values": [
{
"id": "maven-build",
"name": "Maven POM",
"action": "/pom.xml",
"tags": {
"build": "maven",
"format": "build"
}
},
{
"id": "maven-project",
"name": "Maven Project",
"action": "/starter.zip",
"tags": {
"build": "maven",
"format": "project"
}
},
{
"id": "maven-project-2",
"name": "Another Maven Project",
"action": "/starter.zip",
"tags": {
"build": "maven",
"format": "project"
}
},
{
"id": "gradle-build",
"name": "Gradle Config",
"action": "/build.gradle",
"tags": {
"build": "gradle",
"format": "build"
}
},
{
"id": "gradle-project",
"name": "Gradle Project",
"action": "/starter.zip",
"tags": {
"build": "gradle",
"format": "project"
}
},
{
"id": "gradle-project-2",
"name": "Another Gradle Project",
"action": "/starter.zip",
"tags": {
"build": "gradle",
"format": "project"
}
}
]
},
"packaging": {
"type": "single-select",
"default": "jar",
"values": [
{
"id": "jar",
"name": "Jar"
},
{
"id": "war",
"name": "War"
}
]
},
"javaVersion": {
"type": "single-select",
"default": "1.7",
"values": [
{
"id": "1.6",
"name": "1.6"
},
{
"id": "1.7",
"name": "1.7"
},
{
"id": "1.8",
"name": "1.8"
}
]
},
"language": {
"type": "single-select",
"default": "java",
"values": [
{
"id": "groovy",
"name": "Groovy"
},
{
"id": "java",
"name": "Java"
}
]
},
"bootVersion": {
"type": "single-select",
"default": "1.1.8.RELEASE",
"values": [
{
"id": "1.2.0.BUILD-SNAPSHOT",
"name": "1.2.0 (SNAPSHOT)"
},
{
"id": "1.1.8.RELEASE",
"name": "1.1.8"
},
{
"id": "1.1.8.BUILD-SNAPSHOT",
"name": "1.1.8 (SNAPSHOT)"
},
{
"id": "1.0.2.RELEASE",
"name": "1.0.2"
}
]
},
"groupId": {
"type": "text",
"default": "org.test"
},
"artifactId": {
"type": "text",
"default": "demo"
},
"version": {
"type": "text",
"default": "0.0.1-SNAPSHOT"
},
"name": {
"type": "text",
"default": "demo"
},
"description": {
"type": "text",
"default": "Demo project for Spring Boot"
},
"packageName": {
"type": "text",
"default": "demo"
}
}
\ No newline at end of file
"_links": {
"maven-build": {
"href": "http://localhost:8080/pom.xml?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"maven-project": {
"href": "http://localhost:8080/starter.zip?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-build": {
"href": "http://localhost:8080/build.gradle?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-project": {
"href": "http://localhost:8080/starter.zip?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
}
},
"dependencies": {
"type": "hierarchical-multi-select",
"values": [
{
"name": "Core",
"values": [
{
"name": "Security",
"id": "security",
"description": "Security description"
},
{
"name": "AOP",
"id": "aop"
}
]
},
{
"name": "Data",
"values": [
{
"name": "JDBC",
"id": "jdbc"
},
{
"name": "JPA",
"id": "data-jpa"
},
{
"name": "MongoDB",
"id": "data-mongodb"
}
]
}
]
},
"type": {
"type": "action",
"values": [
{
"id": "maven-build",
"name": "Maven POM",
"action": "/pom.xml",
"tags": {
"build": "maven",
"format": "build"
}
},
{
"id": "maven-project",
"name": "Maven Project",
"action": "/starter.zip",
"tags": {
"build": "maven",
"format": "project"
}
},
{
"id": "maven-project-2",
"name": "Another Maven Project",
"action": "/starter.zip",
"tags": {
"build": "maven",
"format": "project"
}
},
{
"id": "gradle-build",
"name": "Gradle Config",
"action": "/build.gradle",
"tags": {
"build": "gradle",
"format": "build"
}
},
{
"id": "gradle-project",
"name": "Gradle Project",
"action": "/starter.zip",
"tags": {
"build": "gradle",
"format": "project"
}
},
{
"id": "gradle-project-2",
"name": "Another Gradle Project",
"action": "/starter.zip",
"tags": {
"build": "gradle",
"format": "project"
}
}
]
},
"packaging": {
"type": "single-select",
"default": "jar",
"values": [
{
"id": "jar",
"name": "Jar"
},
{
"id": "war",
"name": "War"
}
]
},
"javaVersion": {
"type": "single-select",
"default": "1.7",
"values": [
{
"id": "1.6",
"name": "1.6"
},
{
"id": "1.7",
"name": "1.7"
},
{
"id": "1.8",
"name": "1.8"
}
]
},
"language": {
"type": "single-select",
"default": "java",
"values": [
{
"id": "groovy",
"name": "Groovy"
},
{
"id": "java",
"name": "Java"
}
]
},
"bootVersion": {
"type": "single-select",
"default": "1.1.8.RELEASE",
"values": [
{
"id": "1.2.0.BUILD-SNAPSHOT",
"name": "1.2.0 (SNAPSHOT)"
},
{
"id": "1.1.8.RELEASE",
"name": "1.1.8"
},
{
"id": "1.1.8.BUILD-SNAPSHOT",
"name": "1.1.8 (SNAPSHOT)"
},
{
"id": "1.0.2.RELEASE",
"name": "1.0.2"
}
]
},
"groupId": {
"type": "text",
"default": "org.test"
},
"artifactId": {
"type": "text",
"default": "demo"
},
"version": {
"type": "text",
"default": "0.0.1-SNAPSHOT"
},
"name": {
"type": "text",
"default": "demo"
},
"description": {
"type": "text",
"default": "Demo project for Spring Boot"
},
"packageName": {
"type": "text",
"default": "demo"
}
}
......@@ -157,6 +157,11 @@ content into your application; rather pick only the properties that you need.
spring.velocity.suffix=.vm
spring.velocity.view-names= # whitelist of view names that can be resolved
# JERSEY ({sc-spring-boot-autoconfigure}}/jersey/JerseyProperties.{sc-ext}[JerseyProperties])
spring.jersey.type=servlet # servlet or filter
spring.jersey.init= # init params
spring.jersey.filter.order=
# INTERNATIONALIZATION ({sc-spring-boot-autoconfigure}/MessageSourceAutoConfiguration.{sc-ext}[MessageSourceAutoConfiguration])
spring.messages.basename=messages
spring.messages.cacheSeconds=-1
......
......@@ -1084,14 +1084,12 @@ servlet will be registered and mapped to '`+/*+`' by default. You can change the
by adding `@ApplicationPath` to your `ResourceConfig`.
By default Jersey will be set up as a Servlet in a `@Bean` of type
`ServletRegistrationBean` named "jerseyServletRegistration". You can
disable or override that bean by creating one of your own with the
same name. You can also use a Filter instead of a Servlet by setting
`spring.jersey.type=filter` (in which case the `@Bean` to replace or
override is "jerseyFilterRegistration"). The servlet has an `@Order`
which you can set with `spring.jersey.filter.order`. Both the Servlet
and the Filter registrations can be given init parameters using
`spring.jersey.init.*` to specify a map of properties.
`ServletRegistrationBean` named "jerseyServletRegistration". You can disable or override
that bean by creating one of your own with the same name. You can also use a Filter
instead of a Servlet by setting `spring.jersey.type=filter` (in which case the `@Bean` to
replace or override is "jerseyFilterRegistration"). The servlet has an `@Order`which you
can set with `spring.jersey.filter.order`. Both the Servlet and the Filter registrations
can be given init parameters using `spring.jersey.init.*` to specify a map of properties.
There is a {github-code}/spring-boot-samples/spring-boot-sample-jersey[Jersey sample] so
you can see how to set things up. There is also a {github-code}/spring-boot-samples/spring-boot-sample-jersey1[Jersey 1.x sample].
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment