diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricFilterAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricFilterAutoConfiguration.java index 3ab93484df..f3ab0f7827 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricFilterAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/MetricFilterAutoConfiguration.java @@ -64,7 +64,7 @@ public class MetricFilterAutoConfiguration { } @Bean - public MetricsFilter metricFilter() { + public MetricsFilter metricsFilter() { return new MetricsFilter(this.counterService, this.gaugeService, this.properties); } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/AbstractNestedCondition.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/AbstractNestedCondition.java index 927b17b9e2..4baf9d22c1 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/AbstractNestedCondition.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/AbstractNestedCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2015 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. @@ -161,27 +161,63 @@ abstract class AbstractNestedCondition extends SpringBootCondition for (Map.Entry> entry : this.memberConditions .entrySet()) { AnnotationMetadata metadata = entry.getKey(); - for (Condition condition : entry.getValue()) { - outcomes.add(getConditionOutcome(metadata, condition)); - } + List conditions = entry.getValue(); + outcomes.add(new MemberOutcomes(this.context, metadata, conditions) + .getUltimateOutcome()); } return Collections.unmodifiableList(outcomes); } + } + + private static class MemberOutcomes { + + private final ConditionContext context; + + private final AnnotationMetadata metadata; + + private final List outcomes; + + MemberOutcomes(ConditionContext context, AnnotationMetadata metadata, + List conditions) { + this.context = context; + this.metadata = metadata; + this.outcomes = new ArrayList(conditions.size()); + for (Condition condition : conditions) { + this.outcomes.add(getConditionOutcome(metadata, condition)); + } + } + private ConditionOutcome getConditionOutcome(AnnotationMetadata metadata, Condition condition) { - String className = ClassUtils.getShortName(metadata.getClassName()); if (condition instanceof SpringBootCondition) { - ConditionOutcome outcome = ((SpringBootCondition) condition) - .getMatchOutcome(this.context, metadata); - ConditionMessage message = outcome.getConditionMessage() - .append("on member " + className); - return new ConditionOutcome(outcome.isMatch(), message); + return ((SpringBootCondition) condition).getMatchOutcome(this.context, + metadata); } - boolean matches = condition.matches(this.context, metadata); - return new ConditionOutcome(matches, - ConditionMessage.forCondition("NestedCondition") - .because("nested on member " + className)); + return new ConditionOutcome(condition.matches(this.context, metadata), + (ConditionMessage) null); + } + + public ConditionOutcome getUltimateOutcome() { + ConditionMessage.Builder message = ConditionMessage + .forCondition("NestedCondition on " + + ClassUtils.getShortName(this.metadata.getClassName())); + if (this.outcomes.size() == 1) { + ConditionOutcome outcome = this.outcomes.get(0); + return new ConditionOutcome(outcome.isMatch(), + message.because(outcome.getMessage())); + } + List match = new ArrayList(); + List nonMatch = new ArrayList(); + for (ConditionOutcome outcome : this.outcomes) { + (outcome.isMatch() ? match : nonMatch).add(outcome); + } + if (nonMatch.isEmpty()) { + return ConditionOutcome + .match(message.found("matching nested conditions").items(match)); + } + return ConditionOutcome.noMatch( + message.found("non-matching nested conditions").items(nonMatch)); } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java index 338e97abb3..16039c3e9f 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java @@ -132,6 +132,7 @@ public class WebMvcAutoConfiguration { @Bean @ConditionalOnMissingBean(HttpPutFormContentFilter.class) + @ConditionalOnProperty(prefix = "spring.mvc.formcontent.putfilter", name = "enabled", matchIfMissing = true) public OrderedHttpPutFormContentFilter httpPutFormContentFilter() { return new OrderedHttpPutFormContentFilter(); } diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 808b135830..6b06e3d420 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -279,6 +279,12 @@ "description": "Enable resolution of favicon.ico.", "defaultValue": true }, + { + "name": "spring.mvc.formcontent.putfilter.enabled", + "type": "java.lang.Boolean", + "description": "Enable Spring's HttpPutFormContentFilter.", + "defaultValue": true + }, { "name": "spring.rabbitmq.dynamic", "type": "java.lang.Boolean", diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/AnyNestedConditionTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/AnyNestedConditionTests.java index e13b75a293..f60defcb98 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/AnyNestedConditionTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/AnyNestedConditionTests.java @@ -30,12 +30,13 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link AnyNestedCondition}. * * @author Phillip Webb + * @author Dave Syer */ public class AnyNestedConditionTests { @Test public void neither() throws Exception { - AnnotationConfigApplicationContext context = load(OnPropertyAorBCondition.class); + AnnotationConfigApplicationContext context = load(Config.class); assertThat(context.containsBean("myBean")).isFalse(); context.close(); } @@ -91,6 +92,7 @@ public class AnyNestedConditionTests { } + @ConditionalOnExpression("true") @ConditionalOnProperty("b") static class HasPropertyB { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java index 963581a975..d090ce3e79 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java @@ -504,6 +504,12 @@ public class WebMvcAutoConfigurationTests { .hasSize(1); } + @Test + public void httpPutFormContentFilterCanBeDisabled() throws Exception { + load((Class) null, "spring.mvc.formcontent.putfilter.enabled=false"); + assertThat(this.context.getBeansOfType(HttpPutFormContentFilter.class)).isEmpty(); + } + @Test public void customConfigurableWebBindingInitializer() { load(CustomConfigurableWebBindingInitializer.class); diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 346056fb2c..4039573ca7 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -341,6 +341,7 @@ content into your application; rather pick only the properties that you need. spring.mvc.dispatch-trace-request=false # Dispatch TRACE requests to the FrameworkServlet doService method. spring.mvc.dispatch-options-request=true # Dispatch OPTIONS requests to the FrameworkServlet doService method. spring.mvc.favicon.enabled=true # Enable resolution of favicon.ico. + spring.mvc.formcontent.putfilter.enabled=true # Enable Spring's HttpPutFormContentFilter. spring.mvc.ignore-default-model-on-redirect=true # If the content of the "default" model should be ignored during redirect scenarios. spring.mvc.locale= # Locale to use. By default, this locale is overridden by the "Accept-Language" header. spring.mvc.locale-resolver=accept-header # Define how the locale should be resolved. diff --git a/spring-boot-tools/spring-boot-loader-tools/src/main/resources/org/springframework/boot/loader/tools/launch.script b/spring-boot-tools/spring-boot-loader-tools/src/main/resources/org/springframework/boot/loader/tools/launch.script index 505fd166a6..57154ffb17 100755 --- a/spring-boot-tools/spring-boot-loader-tools/src/main/resources/org/springframework/boot/loader/tools/launch.script +++ b/spring-boot-tools/spring-boot-loader-tools/src/main/resources/org/springframework/boot/loader/tools/launch.script @@ -147,7 +147,6 @@ do_start() { mkdir "$PID_FOLDER" &> /dev/null if [[ -n "$run_user" ]]; then checkPermissions || return $? - chown "$run_user" "$PID_FOLDER" chown "$run_user" "$pid_file" chown "$run_user" "$log_file" if [ $USE_START_STOP_DAEMON = true ] && type start-stop-daemon > /dev/null 2>&1; then