/*
* Copyright 2008-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.
* 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 net.hasor.web.invoker;
import net.hasor.core.*;
import net.hasor.core.binder.ApiBinderWrap;
import net.hasor.core.provider.InfoAwareProvider;
import net.hasor.core.provider.InstanceProvider;
import net.hasor.core.utils.BeanUtils;
import net.hasor.core.utils.StringUtils;
import net.hasor.web.*;
import net.hasor.web.annotation.MappingTo;
import net.hasor.web.definition.*;
import net.hasor.web.listener.ContextListenerDefinition;
import net.hasor.web.listener.HttpSessionListenerDefinition;
import net.hasor.web.render.RenderApiBinderImpl;
import net.hasor.web.startup.RuntimeFilter;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpSessionListener;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* 该类是{@link WebApiBinder}接口实现。
* @version : 2017-01-10
* @author 赵永春 (zyc@hasor.net)
*/
public class InvokerWebApiBinder extends ApiBinderWrap implements WebApiBinder {
private final InstanceProvider<String> requestEncoding = new InstanceProvider<String>("");
private final InstanceProvider<String> responseEncoding = new InstanceProvider<String>("");
private ServletVersion curVersion;
private MimeType mimeType;
private RenderApiBinderImpl renderBinder;
//
// ------------------------------------------------------------------------------------------------------
protected InvokerWebApiBinder(ServletVersion curVersion, MimeType mimeType, ApiBinder apiBinder) {
super(apiBinder);
apiBinder.bindType(String.class).nameWith(RuntimeFilter.HTTP_REQUEST_ENCODING_KEY).toProvider(this.requestEncoding);
apiBinder.bindType(String.class).nameWith(RuntimeFilter.HTTP_RESPONSE_ENCODING_KEY).toProvider(this.responseEncoding);
this.curVersion = Hasor.assertIsNotNull(curVersion);
this.mimeType = Hasor.assertIsNotNull(mimeType);
this.renderBinder = new RenderApiBinderImpl(apiBinder) {
};
}
//
// ------------------------------------------------------------------------------------------------------
@Override
public ServletContext getServletContext() {
return (ServletContext) this.getEnvironment().getContext();
}
@Override
public WebApiBinder setRequestCharacter(String encoding) {
this.requestEncoding.set(encoding);
return this;
}
@Override
public WebApiBinder setResponseCharacter(String encoding) {
this.responseEncoding.set(encoding);
return this;
}
@Override
public WebApiBinder setEncodingCharacter(String requestEncoding, String responseEncoding) {
return this.setRequestCharacter(requestEncoding).setResponseCharacter(responseEncoding);
}
//
@Override
public String getMimeType(String suffix) {
return this.mimeType.getMimeType(suffix);
}
@Override
public ServletVersion getServletVersion() {
return this.curVersion;
}
//
// ------------------------------------------------------------------------------------------------------
@Override
public WebApiBinder addPlugin(Class<? extends WebPlugin> webPlugin) {
webPlugin = Hasor.assertIsNotNull(webPlugin);
BindInfo<WebPlugin> bindInfo = this.bindType(WebPlugin.class).to(webPlugin).toInfo();
this.bindType(WebPluginDefinition.class).toInstance(new WebPluginDefinition(bindInfo));
return this;
}
@Override
public WebApiBinder addPlugin(WebPlugin webPlugin) {
webPlugin = Hasor.assertIsNotNull(webPlugin);
BindInfo<WebPlugin> bindInfo = this.bindType(WebPlugin.class).toInstance(webPlugin).toInfo();
this.bindType(WebPluginDefinition.class).toInstance(new WebPluginDefinition(bindInfo));
return this;
}
@Override
public WebApiBinder addPlugin(Provider<? extends WebPlugin> webPlugin) {
webPlugin = Hasor.assertIsNotNull(webPlugin);
BindInfo<WebPlugin> bindInfo = this.bindType(WebPlugin.class).toProvider(webPlugin).toInfo();
this.bindType(WebPluginDefinition.class).toInstance(new WebPluginDefinition(bindInfo));
return this;
}
@Override
public WebApiBinder addPlugin(BindInfo<? extends WebPlugin> webPlugin) {
webPlugin = Hasor.assertIsNotNull(webPlugin);
this.bindType(WebPluginDefinition.class).toInstance(new WebPluginDefinition(webPlugin));
return this;
}
//
// ------------------------------------------------------------------------------------------------------
@Override
public WebApiBinder addSetup(Class<? extends MappingSetup> setup) {
this.bindType(MappingSetup.class).to(Hasor.assertIsNotNull(setup));
return this;
}
@Override
public WebApiBinder addSetup(MappingSetup setup) {
this.bindType(MappingSetup.class).toInstance(Hasor.assertIsNotNull(setup));
return this;
}
@Override
public WebApiBinder addSetup(Provider<? extends MappingSetup> setup) {
this.bindType(MappingSetup.class).toProvider(Hasor.assertIsNotNull(setup));
return this;
}
@Override
public WebApiBinder addSetup(BindInfo<? extends MappingSetup> setup) {
InfoAwareProvider<MappingSetup> provider = new InfoAwareProvider<MappingSetup>(Hasor.assertIsNotNull(setup));
this.bindType(MappingSetup.class).toProvider(Hasor.autoAware(this.getEnvironment(), provider));
return this;
}
//
// ------------------------------------------------------------------------------------------------------
@Override
public void addServletListener(Class<? extends ServletContextListener> targetKey) {
BindInfo<ServletContextListener> listenerRegister = bindType(ServletContextListener.class).to(targetKey).toInfo();
this.addServletListener(listenerRegister);
}
@Override
public void addServletListener(ServletContextListener sessionListener) {
BindInfo<ServletContextListener> listenerRegister = bindType(ServletContextListener.class).toInstance(sessionListener).toInfo();
this.addServletListener(listenerRegister);
}
@Override
public void addServletListener(Provider<? extends ServletContextListener> targetProvider) {
BindInfo<ServletContextListener> listenerRegister = bindType(ServletContextListener.class).toProvider(targetProvider).toInfo();
this.addServletListener(listenerRegister);
}
@Override
public void addServletListener(BindInfo<? extends ServletContextListener> targetRegister) {
this.bindType(ContextListenerDefinition.class).uniqueName().toInstance(new ContextListenerDefinition(targetRegister));
}
@Override
public void addSessionListener(Class<? extends HttpSessionListener> targetKey) {
BindInfo<HttpSessionListener> listenerRegister = bindType(HttpSessionListener.class).to(targetKey).toInfo();
this.addSessionListener(listenerRegister);
}
@Override
public void addSessionListener(HttpSessionListener sessionListener) {
BindInfo<HttpSessionListener> listenerRegister = bindType(HttpSessionListener.class).toInstance(sessionListener).toInfo();
this.addSessionListener(listenerRegister);
}
@Override
public void addSessionListener(Provider<? extends HttpSessionListener> targetProvider) {
BindInfo<HttpSessionListener> listenerRegister = bindType(HttpSessionListener.class).toProvider(targetProvider).toInfo();
this.addSessionListener(listenerRegister);
}
@Override
public void addSessionListener(BindInfo<? extends HttpSessionListener> targetRegister) {
bindType(HttpSessionListenerDefinition.class).uniqueName().toInstance(new HttpSessionListenerDefinition(targetRegister));
}
//
// ------------------------------------------------------------------------------------------------------
@Override
public FilterBindingBuilder<InvokerFilter> filter(String urlPattern, String... morePatterns) {
return new FiltersModuleBinder<InvokerFilter>(InvokerFilter.class, UriPatternType.SERVLET, newArrayList(morePatterns, urlPattern)) {
@Override
protected void bindThrough(int index, String pattern, UriPatternMatcher matcher, BindInfo<? extends InvokerFilter> filterRegister, Map<String, String> initParams) {
filterThrough(index, pattern, matcher, filterRegister, initParams);
}
};
}
@Override
public FilterBindingBuilder<InvokerFilter> filter(String[] morePatterns) {
if (StringUtils.isEmptyArray(morePatterns)) {
throw new NullPointerException("Filter patterns is empty.");
}
return this.filter(null, morePatterns);
}
@Override
public FilterBindingBuilder<InvokerFilter> filterRegex(String regex, String... regexes) {
return new FiltersModuleBinder<InvokerFilter>(InvokerFilter.class, UriPatternType.REGEX, newArrayList(regexes, regex)) {
@Override
protected void bindThrough(int index, String pattern, UriPatternMatcher matcher, BindInfo<? extends InvokerFilter> filterRegister, Map<String, String> initParams) {
filterThrough(index, pattern, matcher, filterRegister, initParams);
}
};
}
@Override
public FilterBindingBuilder<InvokerFilter> filterRegex(String[] regexes) {
if (StringUtils.isEmptyArray(regexes)) {
throw new NullPointerException("Filter regexes is empty.");
}
return this.filterRegex(null, regexes);
}
//
@Override
public FilterBindingBuilder<Filter> jeeFilter(final String urlPattern, final String... morePatterns) {
return new FiltersModuleBinder<Filter>(Filter.class, UriPatternType.SERVLET, newArrayList(morePatterns, urlPattern)) {
@Override
protected void bindThrough(int index, String pattern, UriPatternMatcher matcher, BindInfo<? extends Filter> filterRegister, Map<String, String> initParams) {
jeeFilterThrough(index, pattern, matcher, filterRegister, initParams);
}
};
}
@Override
public FilterBindingBuilder<Filter> jeeFilter(final String[] morePatterns) throws NullPointerException {
if (StringUtils.isEmptyArray(morePatterns)) {
throw new NullPointerException("Filter patterns is empty.");
}
return this.jeeFilter(null, morePatterns);
}
@Override
public FilterBindingBuilder<Filter> jeeFilterRegex(final String regex, final String... regexes) {
return new FiltersModuleBinder<Filter>(Filter.class, UriPatternType.REGEX, newArrayList(regexes, regex)) {
@Override
protected void bindThrough(int index, String pattern, UriPatternMatcher matcher, BindInfo<? extends Filter> filterRegister, Map<String, String> initParams) {
jeeFilterThrough(index, pattern, matcher, filterRegister, initParams);
}
};
}
@Override
public FilterBindingBuilder<Filter> jeeFilterRegex(final String[] regexes) throws NullPointerException {
if (StringUtils.isEmptyArray(regexes)) {
throw new NullPointerException("Filter regexes is empty.");
}
return this.jeeFilterRegex(null, regexes);
}
protected void jeeFilterThrough(int index, String pattern, UriPatternMatcher matcher, BindInfo<? extends Filter> filterRegister, Map<String, String> initParams) {
FilterDefinition define = new FilterDefinition(index, pattern, matcher, filterRegister, initParams);
bindType(AbstractDefinition.class).uniqueName().toInstance(define);
}
protected void filterThrough(int index, String pattern, UriPatternMatcher matcher, BindInfo<? extends InvokerFilter> filterRegister, Map<String, String> initParams) {
InvokeFilterDefinition define = new InvokeFilterDefinition(index, pattern, matcher, filterRegister, initParams);
bindType(AbstractDefinition.class).uniqueName().toInstance(define);
}
private abstract class FiltersModuleBinder<T> implements FilterBindingBuilder<T> {
private final Class<T> targetType;
private final UriPatternType uriPatternType;
private final List<String> uriPatterns;
//
FiltersModuleBinder(Class<T> targetType, final UriPatternType uriPatternType, final List<String> uriPatterns) {
this.targetType = targetType;
this.uriPatternType = uriPatternType;
this.uriPatterns = uriPatterns;
}
@Override
public void through(final Class<? extends T> filterKey) {
this.through(0, filterKey, null);
}
@Override
public void through(final T filter) {
this.through(0, filter, null);
}
@Override
public void through(final Provider<? extends T> filterProvider) {
this.through(0, filterProvider, null);
}
@Override
public void through(BindInfo<? extends T> filterRegister) {
this.through(0, filterRegister, null);
}
@Override
public void through(final Class<? extends T> filterKey, final Map<String, String> initParams) {
this.through(0, filterKey, initParams);
}
@Override
public void through(final T filter, final Map<String, String> initParams) {
this.through(0, filter, initParams);
}
@Override
public void through(final Provider<? extends T> filterProvider, final Map<String, String> initParams) {
this.through(0, filterProvider, initParams);
}
@Override
public void through(BindInfo<? extends T> filterRegister, Map<String, String> initParams) {
this.through(0, filterRegister, initParams);
}
@Override
public void through(final int index, final Class<? extends T> filterKey) {
this.through(index, filterKey, null);
}
@Override
public void through(final int index, final T filter) {
this.through(index, filter, null);
}
@Override
public void through(final int index, final Provider<? extends T> filterProvider) {
this.through(index, filterProvider, null);
}
@Override
public void through(int index, BindInfo<? extends T> filterRegister) {
this.through(index, filterRegister, null);
}
//
@Override
public void through(final int index, final Class<? extends T> filterKey, final Map<String, String> initParams) {
BindInfo<T> filterRegister = bindType(targetType).uniqueName().to(filterKey).toInfo();
this.through(index, filterRegister, initParams);
}
@Override
public void through(final int index, final T filter, final Map<String, String> initParams) {
BindInfo<T> filterRegister = bindType(targetType).uniqueName().toInstance(filter).toInfo();
this.through(index, filterRegister, initParams);
}
@Override
public void through(final int index, final Provider<? extends T> filterProvider, Map<String, String> initParams) {
BindInfo<T> filterRegister = bindType(targetType).uniqueName().toProvider((Provider<T>) filterProvider).toInfo();
this.through(index, filterRegister, initParams);
}
@Override
public void through(int index, BindInfo<? extends T> filterRegister, Map<String, String> initParams) {
if (initParams == null) {
initParams = new HashMap<String, String>();
}
for (String pattern : this.uriPatterns) {
UriPatternMatcher matcher = UriPatternType.get(this.uriPatternType, pattern);
this.bindThrough(index, pattern, matcher, filterRegister, initParams);
}
}
protected abstract void bindThrough(int index, String pattern, UriPatternMatcher matcher, BindInfo<? extends T> filterRegister, Map<String, String> initParams);
}
//
// ------------------------------------------------------------------------------------------------------
protected void jeeServlet(long index, String pattern, BindInfo<? extends HttpServlet> servletRegister, Map<String, String> initParams) {
InMappingServlet define = new InMappingServlet(index, servletRegister, pattern, initParams);
bindType(InMappingDef.class).uniqueName().toInstance(define);/*单例*/
}
@Override
public ServletBindingBuilder jeeServlet(final String urlPattern, final String... morePatterns) {
return new ServletsModuleBuilder(newArrayList(morePatterns, urlPattern));
}
@Override
public ServletBindingBuilder jeeServlet(final String[] morePatterns) {
if (StringUtils.isEmptyArray(morePatterns)) {
throw new NullPointerException("Servlet patterns is empty.");
}
return this.jeeServlet(null, morePatterns);
}
//
private class ServletsModuleBuilder extends MappingToBuilder<HttpServlet> implements ServletBindingBuilder {
ServletsModuleBuilder(final List<String> uriPatterns) {
super(HttpServlet.class, uriPatterns);
}
@Override
public void with(final Class<? extends HttpServlet> servletKey, final Map<String, String> initParams) {
this.with(0, servletKey, initParams);
}
@Override
public void with(final HttpServlet servlet, final Map<String, String> initParams) {
this.with(0, servlet, initParams);
}
@Override
public void with(final Provider<? extends HttpServlet> servletProvider, final Map<String, String> initParams) {
this.with(0, servletProvider, initParams);
}
@Override
public void with(BindInfo<? extends HttpServlet> servletRegister, Map<String, String> initParams) {
this.with(0, servletRegister, initParams);
}
@Override
public void with(int index, BindInfo<? extends HttpServlet> servletRegister) {
this.with(index, servletRegister, null);
}
//
@Override
public void with(final int index, final Class<? extends HttpServlet> servletKey, final Map<String, String> initParams) {
BindInfo<HttpServlet> servletRegister = bindType(HttpServlet.class).uniqueName().to(servletKey).toInfo();
this.with(index, servletRegister, initParams);
}
@Override
public void with(final int index, final HttpServlet servlet, final Map<String, String> initParams) {
BindInfo<HttpServlet> servletRegister = bindType(HttpServlet.class).uniqueName().toInstance(servlet).toInfo();
this.with(index, servletRegister, initParams);
}
@Override
public void with(final int index, final Provider<? extends HttpServlet> servletProvider, Map<String, String> initParams) {
BindInfo<HttpServlet> servletRegister = bindType(HttpServlet.class).uniqueName().toProvider(servletProvider).toInfo();
this.with(index, servletRegister, initParams);
}
@Override
public void with(int index, BindInfo<? extends HttpServlet> servletRegister, Map<String, String> initParams) {
if (initParams == null) {
initParams = new HashMap<String, String>();
}
for (String pattern : this.getUriPatterns()) {
jeeServlet(index, pattern, servletRegister, initParams);
}
}
}
//
// ------------------------------------------------------------------------------------------------------
@Override
public MappingToBindingBuilder<Object> mappingTo(String urlPattern, String... morePatterns) {
return new MappingToBuilder<Object>(Object.class, newArrayList(morePatterns, urlPattern)) {
@Override
public void with(int index, BindInfo<? extends Object> targetInfo) {
List<Method> methodList = BeanUtils.getMethods(targetInfo.getBindType());
for (String pattern : this.getUriPatterns()) {
if (StringUtils.isBlank(pattern))
continue;
//
InMappingDef define = new InMappingDef(index, targetInfo, pattern, methodList, false);
bindType(InMappingDef.class).uniqueName().toInstance(define);
}
}
@Override
protected Class<Object> findBindType(Class<Object> targetClass, Object target) {
if (target instanceof ProviderType) {
return ((ProviderType) target).getType();
} else {
return (Class<Object>) target.getClass();
}
}
@Override
protected Class<Object> findBindType(Class<Object> targetClass, Class<?> targetKey) {
return (Class<Object>) targetKey;
}
@Override
protected Class<Object> findBindType(Class<Object> targetClass, Provider<?> targetProvider) {
if (targetProvider instanceof ProviderType) {
return ((ProviderType) targetProvider).getType();
} else {
return (Class<Object>) targetProvider.get().getClass();
}
}
};
}
@Override
public MappingToBindingBuilder<Object> mappingTo(String[] morePatterns) {
if (StringUtils.isEmptyArray(morePatterns)) {
throw new NullPointerException("mappingTo patterns is empty.");
}
return this.mappingTo(null, morePatterns);
}
//
@Override
public void scanMappingTo() {
this.scanMappingTo(new Matcher<Class<?>>() {
@Override
public boolean matches(Class<?> target) {
return true;
}
});
}
@Override
public void scanMappingTo(String... packages) {
this.scanMappingTo(new Matcher<Class<?>>() {
@Override
public boolean matches(Class<?> target) {
return true;
}
});
}
@Override
public void scanMappingTo(Matcher<Class<?>> matcher, String... packages) {
String[] defaultPackages = this.getEnvironment().getSpanPackage();
String[] scanPackages = (packages == null || packages.length == 0) ? defaultPackages : packages;
//
Set<Class<?>> serviceSet = this.findClass(MappingTo.class, scanPackages);
serviceSet = (serviceSet == null) ? new HashSet<Class<?>>() : new HashSet<Class<?>>(serviceSet);
serviceSet.remove(MappingTo.class);
if (serviceSet.isEmpty()) {
logger.warn("mapingTo -> exit , not found any @MappingTo.");
}
for (Class<?> type : serviceSet) {
loadType(this, type);
}
}
//
// ------------------------------------------------------------------------------------------------------
/**拦截这些后缀的请求,这些请求会被渲染器渲染。*/
public RenderEngineBindingBuilder<RenderEngine> suffix(String urlPattern, String... morePatterns) {
return this.renderBinder.suffix(urlPattern, morePatterns);
}
/**拦截这些后缀的请求,这些请求会被渲染器渲染。*/
public RenderEngineBindingBuilder<RenderEngine> suffix(String[] morePatterns) {
return this.renderBinder.suffix(morePatterns);
}
/**扫描Render注解配置的渲染器。*/
public void scanAnnoRender() {
this.scanAnnoRender(new Matcher<Class<? extends RenderEngine>>() {
@Override
public boolean matches(Class<? extends RenderEngine> target) {
return true;
}
});
}
/**扫描Render注解配置的渲染器。*/
public void scanAnnoRender(String... packages) {
this.scanAnnoRender(new Matcher<Class<? extends RenderEngine>>() {
@Override
public boolean matches(Class<? extends RenderEngine> target) {
return true;
}
});
}
/**扫描Render注解配置的渲染器。*/
public void scanAnnoRender(Matcher<Class<? extends RenderEngine>> matcher, String... packages) {
this.renderBinder.scanAnnoRender(matcher, packages);
}
//
// ------------------------------------------------------------------------------------------------------
//
private abstract class MappingToBuilder<T> implements MappingToBindingBuilder<T> {
private Class<T> targetClass;
private final List<String> uriPatterns;
MappingToBuilder(Class<T> targetClass, List<String> uriPatterns) {
this.targetClass = targetClass;
this.uriPatterns = uriPatterns;
}
@Override
public void with(final Class<? extends T> targetKey) {
this.with(0, targetKey);
}
@Override
public void with(final T target) {
this.with(0, target);
}
@Override
public void with(final Provider<? extends T> targetProvider) {
this.with(0, targetProvider);
}
@Override
public void with(BindInfo<? extends T> targetInfo) {
this.with(0, targetInfo);
}
@Override
public void with(final int index, final Class<? extends T> targetKey) {
Hasor.assertIsNotNull(targetKey);
Class<T> bindType = this.findBindType(this.targetClass, targetKey);
BindInfo<? extends T> info = bindType(bindType).uniqueName().to(targetKey).toInfo();
this.with(index, info);
}
@Override
public void with(final int index, final T target) {
Hasor.assertIsNotNull(target);
Class<T> bindType = this.findBindType(this.targetClass, target);
BindInfo<? extends T> info = bindType(bindType).uniqueName().toInstance(target).toInfo();
this.with(index, info);
}
@Override
public void with(final int index, final Provider<? extends T> targetProvider) {
Hasor.assertIsNotNull(targetProvider);
Class<T> bindType = this.findBindType(this.targetClass, targetProvider);
BindInfo<? extends T> info = bindType(bindType).uniqueName().toProvider(targetProvider).toInfo();
this.with(index, info);
}
public List<String> getUriPatterns() {
return this.uriPatterns;
}
//
//
protected Class<T> findBindType(Class<T> targetClass, T target) {
return targetClass;
}
protected Class<T> findBindType(Class<T> targetClass, Class<? extends T> targetKey) {
return targetClass;
}
protected Class<T> findBindType(Class<T> targetClass, Provider<? extends T> targetProvider) {
return targetClass;
}
public abstract void with(int index, BindInfo<? extends T> targetInfo);
}
//
// ------------------------------------------------------------------------------------------------------
protected static List<String> newArrayList(final String[] arr, final String object) {
ArrayList<String> list = new ArrayList<String>();
if (arr != null) {
Collections.addAll(list, arr);
}
if (object != null) {
list.add(object);
}
return list;
}
public boolean loadType(WebApiBinder apiBinder, Class<?> clazz) {
int modifier = clazz.getModifiers();
if (checkIn(modifier, Modifier.INTERFACE) || checkIn(modifier, Modifier.ABSTRACT)) {
return false;
}
if (!clazz.isAnnotationPresent(MappingTo.class)) {
return false;
}
//
MappingTo mto = clazz.getAnnotation(MappingTo.class);
if (HttpServlet.class.isAssignableFrom(clazz)) {
apiBinder.jeeServlet(mto.value()).with((Class<? extends HttpServlet>) clazz);
logger.info("mapingTo[Servlet] -> type ‘{}’ mappingTo: ‘{}’.", clazz.getName(), mto.value());
} else {
apiBinder.mappingTo(mto.value()).with(clazz);
logger.info("mapingTo[Object] -> type ‘{}’ mappingTo: ‘{}’.", clazz.getName(), mto.value());
}
return true;
}
//
/** 通过位运算决定check是否在data里。 */
private boolean checkIn(final int data, final int check) {
int or = data | check;
return or == data;
}
}