001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.web.servlet; 018 019import java.util.LinkedHashMap; 020import java.util.Map; 021 022import javax.servlet.Registration; 023import javax.servlet.ServletContext; 024 025import org.apache.commons.logging.Log; 026import org.apache.commons.logging.LogFactory; 027 028import org.springframework.core.Conventions; 029import org.springframework.util.Assert; 030import org.springframework.util.StringUtils; 031 032/** 033 * Base class for Servlet 3.0+ {@link javax.servlet.Registration.Dynamic dynamic} based 034 * registration beans. 035 * 036 * @param <D> the dynamic registration result 037 * @author Phillip Webb 038 * @since 2.0.0 039 */ 040public abstract class DynamicRegistrationBean<D extends Registration.Dynamic> 041 extends RegistrationBean { 042 043 private static final Log logger = LogFactory.getLog(RegistrationBean.class); 044 045 private String name; 046 047 private boolean asyncSupported = true; 048 049 private Map<String, String> initParameters = new LinkedHashMap<>(); 050 051 /** 052 * Set the name of this registration. If not specified the bean name will be used. 053 * @param name the name of the registration 054 */ 055 public void setName(String name) { 056 Assert.hasLength(name, "Name must not be empty"); 057 this.name = name; 058 } 059 060 /** 061 * Sets if asynchronous operations are supported for this registration. If not 062 * specified defaults to {@code true}. 063 * @param asyncSupported if async is supported 064 */ 065 public void setAsyncSupported(boolean asyncSupported) { 066 this.asyncSupported = asyncSupported; 067 } 068 069 /** 070 * Returns if asynchronous operations are supported for this registration. 071 * @return if async is supported 072 */ 073 public boolean isAsyncSupported() { 074 return this.asyncSupported; 075 } 076 077 /** 078 * Set init-parameters for this registration. Calling this method will replace any 079 * existing init-parameters. 080 * @param initParameters the init parameters 081 * @see #getInitParameters 082 * @see #addInitParameter 083 */ 084 public void setInitParameters(Map<String, String> initParameters) { 085 Assert.notNull(initParameters, "InitParameters must not be null"); 086 this.initParameters = new LinkedHashMap<>(initParameters); 087 } 088 089 /** 090 * Returns a mutable Map of the registration init-parameters. 091 * @return the init parameters 092 */ 093 public Map<String, String> getInitParameters() { 094 return this.initParameters; 095 } 096 097 /** 098 * Add a single init-parameter, replacing any existing parameter with the same name. 099 * @param name the init-parameter name 100 * @param value the init-parameter value 101 */ 102 public void addInitParameter(String name, String value) { 103 Assert.notNull(name, "Name must not be null"); 104 this.initParameters.put(name, value); 105 } 106 107 @Override 108 protected final void register(String description, ServletContext servletContext) { 109 D registration = addRegistration(description, servletContext); 110 if (registration == null) { 111 logger.info(StringUtils.capitalize(description) + " was not registered " 112 + "(possibly already registered?)"); 113 return; 114 } 115 configure(registration); 116 } 117 118 protected abstract D addRegistration(String description, 119 ServletContext servletContext); 120 121 protected void configure(D registration) { 122 registration.setAsyncSupported(this.asyncSupported); 123 if (!this.initParameters.isEmpty()) { 124 registration.setInitParameters(this.initParameters); 125 } 126 } 127 128 /** 129 * Deduces the name for this registration. Will return user specified name or fallback 130 * to convention based naming. 131 * @param value the object used for convention based names 132 * @return the deduced name 133 */ 134 protected final String getOrDeduceName(Object value) { 135 return (this.name != null) ? this.name : Conventions.getVariableName(value); 136 } 137 138}