, ServletHandlerMethodResolver>();
private HttpMessageConverter>[] messageConverters =
- new HttpMessageConverter[]{new ByteArrayHttpMessageConverter(), new StringHttpMessageConverter(),
+ new HttpMessageConverter[] {new ByteArrayHttpMessageConverter(), new StringHttpMessageConverter(),
new FormHttpMessageConverter(), new SourceHttpMessageConverter()};
+
public AnnotationMethodHandlerAdapter() {
// no restriction of HTTP methods by default
super(false);
}
+
/**
* Set if URL lookup should always use the full path within the current servlet context. Else, the path within the
* current servlet mapping is used if applicable (that is, in the case of a ".../*" servlet mapping in web.xml).
* Default is "false".
- *
* @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath
*/
public void setAlwaysUseFullPath(boolean alwaysUseFullPath) {
@@ -188,7 +187,6 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
* Set if context path and request URI should be URL-decoded. Both are returned undecoded by the Servlet API, in
* contrast to the servlet path.
Uses either the request encoding or the default encoding according to the Servlet
* spec (ISO-8859-1).
- *
* @see org.springframework.web.util.UrlPathHelper#setUrlDecode
*/
public void setUrlDecode(boolean urlDecode) {
@@ -207,7 +205,6 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
/**
* Set the PathMatcher implementation to use for matching URL paths against registered URL patterns. Default is
* AntPathMatcher.
- *
* @see org.springframework.util.AntPathMatcher
*/
public void setPathMatcher(PathMatcher pathMatcher) {
@@ -217,7 +214,8 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
/**
* Set the MethodNameResolver to use for resolving default handler methods (carrying an empty
- * @RequestMapping annotation).
Will only kick in when the handler method cannot be resolved uniquely
+ * @RequestMapping annotation).
+ *
Will only kick in when the handler method cannot be resolved uniquely
* through the annotation metadata already.
*/
public void setMethodNameResolver(MethodNameResolver methodNameResolver) {
@@ -225,15 +223,16 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
}
/**
- * Specify a WebBindingInitializer which will apply pre-configured configuration to every DataBinder that this
- * controller uses.
+ * Specify a WebBindingInitializer which will apply pre-configured configuration to every
+ * DataBinder that this controller uses.
*/
public void setWebBindingInitializer(WebBindingInitializer webBindingInitializer) {
this.webBindingInitializer = webBindingInitializer;
}
/**
- * Specify the strategy to store session attributes with.
Default is {@link org.springframework.web.bind.support.DefaultSessionAttributeStore},
+ * Specify the strategy to store session attributes with.
+ *
Default is {@link org.springframework.web.bind.support.DefaultSessionAttributeStore},
* storing session attributes in the HttpSession, using the same attribute name as in the model.
*/
public void setSessionAttributeStore(SessionAttributeStore sessionAttributeStore) {
@@ -243,10 +242,10 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
/**
* Cache content produced by @SessionAttributes annotated handlers for the given number of seconds.
- * Default is 0, preventing caching completely.
In contrast to the "cacheSeconds" property which will apply to all
+ * Default is 0, preventing caching completely.
+ *
In contrast to the "cacheSeconds" property which will apply to all
* general handlers (but not to @SessionAttributes annotated handlers), this setting will apply to
* @SessionAttributes annotated handlers only.
- *
* @see #setCacheSeconds
* @see org.springframework.web.bind.annotation.SessionAttributes
*/
@@ -255,15 +254,17 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
}
/**
- * Set if controller execution should be synchronized on the session, to serialize parallel invocations from the same
- * client.
More specifically, the execution of each handler method will get synchronized if this flag is "true". The
- * best available session mutex will be used for the synchronization; ideally, this will be a mutex exposed by
- * HttpSessionMutexListener.
The session mutex is guaranteed to be the same object during the entire lifetime of the
- * session, available under the key defined by the SESSION_MUTEX_ATTRIBUTE constant. It serves as a safe
- * reference to synchronize on for locking on the current session.
In many cases, the HttpSession reference itself
- * is a safe mutex as well, since it will always be the same object reference for the same active logical session.
- * However, this is not guaranteed across different servlet containers; the only 100% safe way is a session mutex.
- *
+ * Set if controller execution should be synchronized on the session, to serialize
+ * parallel invocations from the same client.
+ *
More specifically, the execution of each handler method will get synchronized if this
+ * flag is "true". The best available session mutex will be used for the synchronization;
+ * ideally, this will be a mutex exposed by HttpSessionMutexListener.
+ *
The session mutex is guaranteed to be the same object during the entire lifetime of the
+ * session, available under the key defined by the SESSION_MUTEX_ATTRIBUTE constant.
+ * It serves as a safe reference to synchronize on for locking on the current session.
+ *
In many cases, the HttpSession reference itself a safe mutex as well, since it will
+ * always be the same object reference for the same active logical session. However, this is
+ * not guaranteed across different servlet containers; the only 100% safe way is a session mutex.
* @see org.springframework.web.util.HttpSessionMutexListener
* @see org.springframework.web.util.WebUtils#getSessionMutex(javax.servlet.http.HttpSession)
*/
@@ -273,7 +274,8 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
/**
* Set the ParameterNameDiscoverer to use for resolving method parameter names if needed (e.g. for default attribute
- * names).
Default is a {@link org.springframework.core.LocalVariableTableParameterNameDiscoverer}.
+ * names).
+ *
Default is a {@link org.springframework.core.LocalVariableTableParameterNameDiscoverer}.
*/
public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) {
this.parameterNameDiscoverer = parameterNameDiscoverer;
@@ -316,10 +318,10 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
* responses.
*/
public void setMessageConverters(HttpMessageConverter>[] messageConverters) {
- Assert.notEmpty(messageConverters, "'messageConverters' must not be empty");
this.messageConverters = messageConverters;
}
+
public boolean supports(Object handler) {
return getMethodResolver(handler).hasHandlerMethods();
}
@@ -372,12 +374,12 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
}
/**
- * Template method for creating a new ServletRequestDataBinder instance.
The default implementation creates a
- * standard ServletRequestDataBinder. This can be overridden for custom ServletRequestDataBinder subclasses.
- *
+ * Template method for creating a new ServletRequestDataBinder instance.
+ *
The default implementation creates a standard ServletRequestDataBinder.
+ * This can be overridden for custom ServletRequestDataBinder subclasses.
* @param request current HTTP request
- * @param target the target object to bind onto (or null if the binder is just used to convert a plain
- * parameter value)
+ * @param target the target object to bind onto (or null
+ * if the binder is just used to convert a plain parameter value)
* @param objectName the objectName of the target object
* @return the ServletRequestDataBinder instance to use
* @throws Exception in case of invalid state or arguments
@@ -390,7 +392,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
return new ServletRequestDataBinder(target, objectName);
}
- /** Build a HandlerMethodResolver for the given handler type. */
+ /**
+ * Build a HandlerMethodResolver for the given handler type.
+ */
private ServletHandlerMethodResolver getMethodResolver(Object handler) {
Class handlerClass = ClassUtils.getUserClass(handler);
ServletHandlerMethodResolver resolver = this.methodResolverCache.get(handlerClass);
@@ -401,7 +405,10 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
return resolver;
}
- /** Servlet-specific subclass of {@link HandlerMethodResolver}. */
+
+ /**
+ * Servlet-specific subclass of {@link HandlerMethodResolver}.
+ */
private class ServletHandlerMethodResolver extends HandlerMethodResolver {
private ServletHandlerMethodResolver(Class> handlerType) {
@@ -587,7 +594,10 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
}
}
- /** Servlet-specific subclass of {@link HandlerMethodInvoker}. */
+
+ /**
+ * Servlet-specific subclass of {@link HandlerMethodInvoker}.
+ */
private class ServletHandlerMethodInvoker extends HandlerMethodInvoker {
private boolean responseArgumentUsed = false;
@@ -780,16 +790,18 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
HttpOutputMessage outputMessage = new ServletServerHttpResponse(webRequest.getResponse());
Class> returnValueType = returnValue.getClass();
List allSupportedMediaTypes = new ArrayList();
- for (HttpMessageConverter messageConverter : messageConverters) {
- allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
- if (messageConverter.supports(returnValueType)) {
- for (Object o : messageConverter.getSupportedMediaTypes()) {
- MediaType supportedMediaType = (MediaType) o;
- for (MediaType acceptedMediaType : acceptedMediaTypes) {
- if (supportedMediaType.includes(acceptedMediaType)) {
- messageConverter.write(returnValue, outputMessage);
- responseArgumentUsed = true;
- return;
+ if (messageConverters != null) {
+ for (HttpMessageConverter messageConverter : messageConverters) {
+ allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
+ if (messageConverter.supports(returnValueType)) {
+ for (Object o : messageConverter.getSupportedMediaTypes()) {
+ MediaType supportedMediaType = (MediaType) o;
+ for (MediaType acceptedMediaType : acceptedMediaTypes) {
+ if (supportedMediaType.includes(acceptedMediaType)) {
+ messageConverter.write(returnValue, outputMessage);
+ responseArgumentUsed = true;
+ return;
+ }
}
}
}
@@ -799,6 +811,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
}
}
+
static class RequestMappingInfo {
String[] paths = new String[0];
diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/annotation/ServletAnnotationControllerTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/annotation/ServletAnnotationControllerTests.java
index 0bfffa8f36e..a402872276b 100644
--- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/annotation/ServletAnnotationControllerTests.java
+++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/annotation/ServletAnnotationControllerTests.java
@@ -5,7 +5,7 @@
* 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
+ * http://www.apache.org/licensesch/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,
@@ -16,14 +16,6 @@
package org.springframework.web.servlet.mvc.annotation;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
import java.io.IOException;
import java.io.Serializable;
import java.io.Writer;
@@ -43,7 +35,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
-
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@@ -52,7 +43,9 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
+import static org.junit.Assert.*;
import org.junit.Test;
+
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.aop.interceptor.SimpleTraceInterceptor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
@@ -80,6 +73,8 @@ import org.springframework.stereotype.Controller;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
+import org.springframework.ui.format.support.GenericFormatterRegistry;
+import org.springframework.ui.format.date.DateFormatter;
import org.springframework.util.SerializationTestUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
@@ -95,6 +90,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.bind.support.WebArgumentResolver;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.context.WebApplicationContext;
@@ -405,7 +401,7 @@ public class ServletAnnotationControllerTests {
}
@Test
- public void commandProvidingFormController() throws Exception {
+ public void commandProvidingFormControllerWithCustomEditor() throws Exception {
@SuppressWarnings("serial") DispatcherServlet servlet = new DispatcherServlet() {
@Override
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) {
@@ -431,6 +427,37 @@ public class ServletAnnotationControllerTests {
assertEquals("myView-String:myDefaultName-typeMismatch-tb1-myOriginalValue", response.getContentAsString());
}
+ @Test
+ public void commandProvidingFormControllerWithFormatter() throws Exception {
+ @SuppressWarnings("serial") DispatcherServlet servlet = new DispatcherServlet() {
+ @Override
+ protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) {
+ GenericWebApplicationContext wac = new GenericWebApplicationContext();
+ wac.registerBeanDefinition("controller",
+ new RootBeanDefinition(MyCommandProvidingFormController.class));
+ wac.registerBeanDefinition("viewResolver", new RootBeanDefinition(TestViewResolver.class));
+ RootBeanDefinition registryDef = new RootBeanDefinition(GenericFormatterRegistry.class);
+ registryDef.getPropertyValues().addPropertyValue("formatters", new DateFormatter("yyyy-MM-dd"));
+ RootBeanDefinition initializerDef = new RootBeanDefinition(ConfigurableWebBindingInitializer.class);
+ initializerDef.getPropertyValues().addPropertyValue("formatterRegistry", registryDef);
+ RootBeanDefinition adapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class);
+ adapterDef.getPropertyValues().addPropertyValue("webBindingInitializer", initializerDef);
+ wac.registerBeanDefinition("handlerAdapter", adapterDef);
+ wac.refresh();
+ return wac;
+ }
+ };
+ servlet.init(new MockServletConfig());
+
+ MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath.do");
+ request.addParameter("defaultName", "myDefaultName");
+ request.addParameter("age", "value2");
+ request.addParameter("date", "2007-10-02");
+ MockHttpServletResponse response = new MockHttpServletResponse();
+ servlet.service(request, response);
+ assertEquals("myView-String:myDefaultName-typeMismatch-tb1-myOriginalValue", response.getContentAsString());
+ }
+
@Test
public void typedCommandProvidingFormController() throws Exception {
@SuppressWarnings("serial") DispatcherServlet servlet = new DispatcherServlet() {
diff --git a/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodInvoker.java b/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodInvoker.java
index 0f8628bdf8c..6137a4adc0c 100644
--- a/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodInvoker.java
+++ b/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodInvoker.java
@@ -75,8 +75,8 @@ import org.springframework.web.multipart.MultipartRequest;
*
* @author Juergen Hoeller
* @author Arjen Poutsma
- * @see #invokeHandlerMethod
* @since 2.5.2
+ * @see #invokeHandlerMethod
*/
public class HandlerMethodInvoker {
@@ -93,18 +93,17 @@ public class HandlerMethodInvoker {
private final WebArgumentResolver[] customArgumentResolvers;
- private final SimpleSessionStatus sessionStatus = new SimpleSessionStatus();
-
private final HttpMessageConverter[] messageConverters;
+ private final SimpleSessionStatus sessionStatus = new SimpleSessionStatus();
+
public HandlerMethodInvoker(HandlerMethodResolver methodResolver) {
this(methodResolver, null);
}
public HandlerMethodInvoker(HandlerMethodResolver methodResolver, WebBindingInitializer bindingInitializer) {
- this(methodResolver, bindingInitializer, new DefaultSessionAttributeStore(), null, new WebArgumentResolver[0],
- new HttpMessageConverter[0]);
+ this(methodResolver, bindingInitializer, new DefaultSessionAttributeStore(), null, null, null);
}
public HandlerMethodInvoker(HandlerMethodResolver methodResolver, WebBindingInitializer bindingInitializer,
@@ -379,7 +378,7 @@ public class HandlerMethodInvoker {
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
throws Exception {
- Class paramType = methodParam.getParameterType();
+ Class> paramType = methodParam.getParameterType();
if (paramName.length() == 0) {
paramName = getRequiredParameterName(methodParam);
}
@@ -411,7 +410,7 @@ public class HandlerMethodInvoker {
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
throws Exception {
- Class paramType = methodParam.getParameterType();
+ Class> paramType = methodParam.getParameterType();
if (headerName.length() == 0) {
headerName = getRequiredParameterName(methodParam);
}
@@ -455,12 +454,14 @@ public class HandlerMethodInvoker {
"Cannot extract @RequestBody parameter (" + builder.toString() + "): no Content-Type found");
}
List allSupportedMediaTypes = new ArrayList();
- for (HttpMessageConverter> messageConverter : messageConverters) {
- allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
- if (messageConverter.supports(paramType)) {
- for (MediaType supportedMediaType : messageConverter.getSupportedMediaTypes()) {
- if (supportedMediaType.includes(contentType)) {
- return messageConverter.read(paramType, inputMessage);
+ if (this.messageConverters != null) {
+ for (HttpMessageConverter> messageConverter : this.messageConverters) {
+ allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
+ if (messageConverter.supports(paramType)) {
+ for (MediaType supportedMediaType : messageConverter.getSupportedMediaTypes()) {
+ if (supportedMediaType.includes(contentType)) {
+ return messageConverter.read(paramType, inputMessage);
+ }
}
}
}
@@ -480,7 +481,7 @@ public class HandlerMethodInvoker {
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
throws Exception {
- Class paramType = methodParam.getParameterType();
+ Class> paramType = methodParam.getParameterType();
if (cookieName.length() == 0) {
cookieName = getRequiredParameterName(methodParam);
}
@@ -512,7 +513,7 @@ public class HandlerMethodInvoker {
private Object resolvePathVariable(String pathVarName, MethodParameter methodParam,
NativeWebRequest webRequest, Object handlerForInitBinderCall) throws Exception {
- Class paramType = methodParam.getParameterType();
+ Class> paramType = methodParam.getParameterType();
if (pathVarName.length() == 0) {
pathVarName = getRequiredParameterName(methodParam);
}
@@ -565,8 +566,8 @@ public class HandlerMethodInvoker {
if ("".equals(name)) {
name = Conventions.getVariableNameForParameter(methodParam);
}
- Class paramType = methodParam.getParameterType();
- Object bindObject = null;
+ Class> paramType = methodParam.getParameterType();
+ Object bindObject;
if (implicitModel.containsKey(name)) {
bindObject = implicitModel.get(name);
}
diff --git a/org.springframework.web/src/main/java/org/springframework/web/bind/support/ConfigurableWebBindingInitializer.java b/org.springframework.web/src/main/java/org/springframework/web/bind/support/ConfigurableWebBindingInitializer.java
index 27a1361b0d2..cb4c09b3ace 100644
--- a/org.springframework.web/src/main/java/org/springframework/web/bind/support/ConfigurableWebBindingInitializer.java
+++ b/org.springframework.web/src/main/java/org/springframework/web/bind/support/ConfigurableWebBindingInitializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2007 the original author or authors.
+ * Copyright 2002-2009 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.
@@ -17,6 +17,7 @@
package org.springframework.web.bind.support;
import org.springframework.beans.PropertyEditorRegistrar;
+import org.springframework.ui.format.FormatterRegistry;
import org.springframework.validation.BindingErrorProcessor;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.web.bind.WebDataBinder;
@@ -42,6 +43,8 @@ public class ConfigurableWebBindingInitializer implements WebBindingInitializer
private BindingErrorProcessor bindingErrorProcessor;
+ private FormatterRegistry formatterRegistry;
+
private PropertyEditorRegistrar[] propertyEditorRegistrars;
@@ -91,24 +94,35 @@ public class ConfigurableWebBindingInitializer implements WebBindingInitializer
}
/**
- * Specify a single PropertyEditorRegistrar to be applied
- * to every DataBinder that this controller uses.
+ * Specify a FormatterRegistry which will apply to every DataBinder.
+ */
+ public final void setFormatterRegistry(FormatterRegistry formatterRegistry) {
+ this.formatterRegistry = formatterRegistry;
+ }
+
+ /**
+ * Return a FormatterRegistry which will apply to every DataBinder.
+ */
+ public final FormatterRegistry getFormatterRegistry() {
+ return this.formatterRegistry;
+ }
+
+ /**
+ * Specify a single PropertyEditorRegistrar to be applied to every DataBinder.
*/
public final void setPropertyEditorRegistrar(PropertyEditorRegistrar propertyEditorRegistrar) {
this.propertyEditorRegistrars = new PropertyEditorRegistrar[] {propertyEditorRegistrar};
}
/**
- * Specify multiple PropertyEditorRegistrars to be applied
- * to every DataBinder that this controller uses.
+ * Specify multiple PropertyEditorRegistrars to be applied to every DataBinder.
*/
public final void setPropertyEditorRegistrars(PropertyEditorRegistrar[] propertyEditorRegistrars) {
this.propertyEditorRegistrars = propertyEditorRegistrars;
}
/**
- * Return the PropertyEditorRegistrars to be applied
- * to every DataBinder that this controller uses.
+ * Return the PropertyEditorRegistrars to be applied to every DataBinder.
*/
public final PropertyEditorRegistrar[] getPropertyEditorRegistrars() {
return this.propertyEditorRegistrars;
@@ -125,9 +139,12 @@ public class ConfigurableWebBindingInitializer implements WebBindingInitializer
if (this.bindingErrorProcessor != null) {
binder.setBindingErrorProcessor(this.bindingErrorProcessor);
}
+ if (this.formatterRegistry != null) {
+ binder.setFormatterRegistry(this.formatterRegistry);
+ }
if (this.propertyEditorRegistrars != null) {
- for (int i = 0; i < this.propertyEditorRegistrars.length; i++) {
- this.propertyEditorRegistrars[i].registerCustomEditors(binder);
+ for (PropertyEditorRegistrar propertyEditorRegistrar : this.propertyEditorRegistrars) {
+ propertyEditorRegistrar.registerCustomEditors(binder);
}
}
}