All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.hasor.web.WebApiBinder Maven / Gradle / Ivy

There is a newer version: 4.2.5
Show newest version
/*
 * 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;
import net.hasor.core.ApiBinder;
import net.hasor.core.BindInfo;
import net.hasor.core.Provider;
import net.hasor.core.TypeSupplier;
import net.hasor.core.aop.AsmTools;
import net.hasor.core.exts.aop.Matchers;
import net.hasor.utils.ArrayUtils;
import net.hasor.utils.ResourcesUtils;
import net.hasor.web.annotation.MappingTo;
import net.hasor.web.render.Render;
import net.hasor.web.render.RenderEngine;

import javax.servlet.Filter;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Modifier;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * 提供了注册Servlet和Filter的方法。
 * @version : 2016-12-26
 * @author 赵永春 ([email protected])
 */
public interface WebApiBinder extends ApiBinder, MimeType {
    /**获取ServletContext对象。*/
    public ServletContext getServletContext();

    /** 设置请求编码 */
    public WebApiBinder setRequestCharacter(String encoding);

    /** 设置响应编码 */
    public WebApiBinder setResponseCharacter(String encoding);

    /** 设置请求响应编码 */
    public default WebApiBinder setEncodingCharacter(String requestEncoding, String responseEncoding) {
        return this.setRequestCharacter(requestEncoding).setResponseCharacter(responseEncoding);
    }

    /**获取容器支持的Servlet版本。*/
    public ServletVersion getServletVersion();

    /**使用 MappingTo 表达式,创建一个{@link ServletBindingBuilder}。*/
    public default ServletBindingBuilder jeeServlet(String urlPattern, String... morePatterns) {
        return this.jeeServlet(ArrayUtils.add(morePatterns, urlPattern));
    }

    /**使用 MappingTo 表达式,创建一个{@link ServletBindingBuilder}。*/
    public ServletBindingBuilder jeeServlet(String[] morePatterns);

    /**使用 MappingTo 表达式,创建一个{@link MappingToBindingBuilder}。*/
    public default  MappingToBindingBuilder mappingTo(String urlPattern, String... morePatterns) {
        return this.mappingTo(ArrayUtils.add(morePatterns, urlPattern));
    }

    /**使用 MappingTo 表达式,创建一个{@link MappingToBindingBuilder}。*/
    public  MappingToBindingBuilder mappingTo(String[] morePatterns);

    /** 加载带有 @MappingTo 注解的类。 */
    public default WebApiBinder loadMappingTo(Set> udfTypeSet) {
        return this.loadMappingTo(udfTypeSet, Matchers.anyClass(), null);
    }

    /** 加载带有 @MappingTo 注解的类。 */
    public default WebApiBinder loadMappingTo(Set> maybeUdfTypeSet, Predicate> matcher, TypeSupplier typeSupplier) {
        if (maybeUdfTypeSet != null && !maybeUdfTypeSet.isEmpty()) {
            maybeUdfTypeSet.stream()//
                    .filter(matcher)//
                    .filter(Matchers.annotatedWithClass(MappingTo.class))//
                    .forEach(aClass -> loadMappingTo(aClass, typeSupplier));
        }
        return this;
    }

    /** 加载带有 @MappingTo 注解的类。 */
    public default WebApiBinder loadMappingTo(Class mappingType) {
        return loadMappingTo(mappingType, null);
    }

    /** 加载带有 @MappingTo 注解的类。 */
    public default WebApiBinder loadMappingTo(Class mappingType, final TypeSupplier typeSupplier) {
        Objects.requireNonNull(mappingType, "class is null.");
        int modifier = mappingType.getModifiers();
        if (AsmTools.checkOr(modifier, Modifier.INTERFACE, Modifier.ABSTRACT) || mappingType.isArray() || mappingType.isEnum()) {
            throw new IllegalStateException(mappingType.getName() + " must be normal Bean");
        }
        MappingTo[] annotationsByType = mappingType.getAnnotationsByType(MappingTo.class);
        if (annotationsByType == null || annotationsByType.length == 0) {
            throw new IllegalStateException(mappingType.getName() + " must be configure @MappingTo");
        }
        //
        if (HttpServlet.class.isAssignableFrom(mappingType)) {
            final Class httpServletType = (Class) mappingType;
            Arrays.stream(annotationsByType).peek(mappingTo -> {
            }).forEach(mappingTo -> {
                if (!isSingleton(mappingType)) {
                    throw new IllegalStateException("HttpServlet " + mappingType + " must be Singleton.");
                }
                if (typeSupplier != null) {
                    jeeServlet(mappingTo.value()).with(() -> typeSupplier.get(httpServletType));
                } else {
                    jeeServlet(mappingTo.value()).with(httpServletType);
                }
            });
        } else {
            final Class mappingObjType = (Class) mappingType;
            Arrays.stream(annotationsByType).peek(mappingTo -> {
            }).forEach(mappingTo -> {
                if (typeSupplier != null) {
                    mappingTo(mappingTo.value()).with(mappingObjType, () -> typeSupplier.get(mappingObjType));
                } else {
                    mappingTo(mappingTo.value()).with(mappingType);
                }
            });
        }
        return this;
    }

    /**使用传统表达式,创建一个{@link FilterBindingBuilder}。*/
    public default FilterBindingBuilder filter(String urlPattern, String... morePatterns) {
        return this.filter(ArrayUtils.add(morePatterns, urlPattern));
    }

    /**使用传统表达式,创建一个{@link FilterBindingBuilder}。*/
    public FilterBindingBuilder filter(String[] morePatterns);

    /**使用正则表达式,创建一个{@link FilterBindingBuilder}。*/
    public default FilterBindingBuilder filterRegex(String regex, String... regexes) {
        return this.filter(ArrayUtils.add(regexes, regex));
    }

    /**使用正则表达式,创建一个{@link FilterBindingBuilder}。*/
    public FilterBindingBuilder filterRegex(String[] regexes);

    /**使用传统表达式,创建一个{@link FilterBindingBuilder}。*/
    public default FilterBindingBuilder jeeFilter(String urlPattern, String... morePatterns) {
        return this.jeeFilter(ArrayUtils.add(morePatterns, urlPattern));
    }

    /**使用传统表达式,创建一个{@link FilterBindingBuilder}。*/
    public FilterBindingBuilder jeeFilter(String[] morePatterns);

    /**使用正则表达式,创建一个{@link FilterBindingBuilder}。*/
    public default FilterBindingBuilder jeeFilterRegex(String regex, String... regexes) {
        return this.jeeFilterRegex(ArrayUtils.add(regexes, regex));
    }

    /**使用正则表达式,创建一个{@link FilterBindingBuilder}。*/
    public FilterBindingBuilder jeeFilterRegex(String[] regexes);

    public void addMimeType(String type, String mimeType);

    public default void loadMimeType(String resource) throws IOException {
        loadMimeType(StandardCharsets.UTF_8, resource);
    }

    public default void loadMimeType(InputStream inputStream) throws IOException {
        loadMimeType(StandardCharsets.UTF_8, inputStream);
    }

    public default void loadMimeType(Charset charset, String resource) throws IOException {
        loadMimeType(charset, Objects.requireNonNull(ResourcesUtils.getResourceAsStream(resource), resource + " is not exist"));
    }

    public default void loadMimeType(Charset charset, InputStream inputStream) throws IOException {
        loadMimeType(new InputStreamReader(inputStream, charset));
    }

    public void loadMimeType(Reader reader) throws IOException;

    /** 负责配置Filter */
    public static interface FilterBindingBuilder {
        public default void through(Class filterKey) {
            this.through(0, filterKey, null);
        }

        public default void through(T filter) {
            this.through(0, filter, null);
        }

        public default void through(Supplier filterProvider) {
            this.through(0, filterProvider, null);
        }

        public default void through(BindInfo filterRegister) {
            this.through(0, filterRegister, null);
        }

        public default void through(Class filterKey, Map initParams) {
            this.through(0, filterKey, initParams);
        }

        public default void through(T filter, Map initParams) {
            this.through(0, filter, initParams);
        }

        public default void through(Supplier filterProvider, Map initParams) {
            this.through(0, filterProvider, initParams);
        }

        public default void through(BindInfo filterRegister, Map initParams) {
            this.through(0, filterRegister, initParams);
        }

        public default void through(int index, Class filterKey) {
            this.through(index, filterKey, null);
        }

        public default void through(int index, T filter) {
            this.through(index, filter, null);
        }

        public default void through(int index, Supplier filterProvider) {
            this.through(index, filterProvider, null);
        }

        public default void through(int index, BindInfo filterRegister) {
            this.through(index, filterRegister, null);
        }

        public void through(int index, Class filterKey, Map initParams);

        public void through(int index, T filter, Map initParams);

        public void through(int index, Supplier filterProvider, Map initParams);

        public void through(int index, BindInfo filterRegister, Map initParams);
    }

    /**负责配置Servlet。*/
    public static interface ServletBindingBuilder {
        public default void with(Class targetKey) {
            with(0, targetKey, null);
        }

        public default void with(HttpServlet target) {
            with(0, target, null);
        }

        public default void with(Supplier targetProvider) {
            with(0, targetProvider, null);
        }

        public default void with(BindInfo targetInfo) {
            with(0, targetInfo, null);
        }

        public default void with(Class servletKey, Map initParams) {
            this.with(0, servletKey, initParams);
        }

        public default void with(HttpServlet servlet, Map initParams) {
            this.with(0, servlet, initParams);
        }

        public default void with(Supplier servletProvider, Map initParams) {
            this.with(0, servletProvider, initParams);
        }

        public default void with(BindInfo servletRegister, Map initParams) {
            this.with(0, servletRegister, initParams);
        }

        public default void with(int index, Class targetKey) {
            this.with(index, targetKey, null);
        }

        public default void with(int index, HttpServlet target) {
            this.with(index, target, null);
        }

        public default void with(int index, Supplier targetProvider) {
            this.with(index, targetProvider, null);
        }

        public default void with(int index, BindInfo targetInfo) {
            this.with(index, targetInfo, null);
        }

        public void with(int index, Class servletKey, Map initParams);

        public void with(int index, HttpServlet servlet, Map initParams);

        public void with(int index, Supplier servletProvider, Map initParams);

        public void with(int index, BindInfo servletRegister, Map initParams);
    }

    /**负责配置MappingTo。*/
    public static interface MappingToBindingBuilder {
        public default void with(Class targetKey) {
            with(0, targetKey);
        }

        public default void with(T target) {
            with(0, target);
        }

        public default void with(Class referKey, Supplier targetProvider) {
            with(0, referKey, targetProvider);
        }

        public default void with(BindInfo targetInfo) {
            with(0, targetInfo);
        }

        public void with(int index, Class targetKey);

        public void with(int index, T target);

        public void with(int index, Class referKey, Supplier targetProvider);

        public void with(int index, BindInfo targetInfo);
    }
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    /** 加载带有 @Render注解配置的渲染器。 */
    public default WebApiBinder loadRender(Set> udfTypeSet) {
        return this.loadRender(udfTypeSet, Matchers.anyClass(), null);
    }

    /** 加载带有 @Render注解配置的渲染器。 */
    public default WebApiBinder loadRender(Set> maybeUdfTypeSet, Predicate> matcher, TypeSupplier typeSupplier) {
        if (maybeUdfTypeSet != null && !maybeUdfTypeSet.isEmpty()) {
            maybeUdfTypeSet.stream()//
                    .filter(matcher)//
                    .filter(Matchers.annotatedWithClass(Render.class))//
                    .forEach(aClass -> loadRender(aClass, typeSupplier));
        }
        return this;
    }

    /** 加载 @Render注解配置的渲染器。*/
    public default WebApiBinder loadRender(Class renderClass) {
        return loadRender(renderClass, null);
    }

    /** 加载 @Render注解配置的渲染器。*/
    public default WebApiBinder loadRender(Class renderClass, TypeSupplier typeSupplier) {
        Objects.requireNonNull(renderClass, "class is null.");
        int modifier = renderClass.getModifiers();
        if (AsmTools.checkOr(modifier, Modifier.INTERFACE, Modifier.ABSTRACT) || renderClass.isArray() || renderClass.isEnum()) {
            throw new IllegalStateException(renderClass.getName() + " must be normal Bean");
        }
        if (!renderClass.isAnnotationPresent(Render.class)) {
            throw new IllegalStateException(renderClass.getName() + " must be configure @Render");
        }
        if (!RenderEngine.class.isAssignableFrom(renderClass)) {
            throw new IllegalStateException(renderClass.getName() + " must be implements RenderEngine.");
        }
        //
        Class engineClass = (Class) renderClass;
        Render renderInfo = renderClass.getAnnotation(Render.class);
        if (renderInfo != null && renderInfo.value().length > 0) {
            for (String renderName : renderInfo.value()) {
                if (typeSupplier == null) {
                    addRender(renderName).to(engineClass);
                } else {
                    addRender(renderName).toProvider(() -> {
                        return typeSupplier.get(engineClass);
                    });
                }
            }
        }
        return this;
    }

    /**
     * 添加一个渲染器,用来将 Action 请求的结果渲染成页面。
     * @param renderName 渲染器名称
     */
    public RenderEngineBindingBuilder addRender(String renderName);

    /** 负责配置RenderEngine。*/
    public static interface RenderEngineBindingBuilder {
        /**绑定实现。*/
        public  void to(Class renderEngineType);

        /**绑定实现。*/
        public default void toInstance(RenderEngine renderEngine) {
            this.toProvider(Provider.of(renderEngine));
        }

        /**绑定实现。*/
        public void toProvider(Supplier renderEngineProvider);

        /**绑定实现。*/
        public void bindToInfo(BindInfo renderEngineInfo);
    }
    //
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //    /** 创建一个映射,当匹配某个URL的时候使用指定的 Render 来渲染。如果存在多条规则按照 index 顺序裁决 index 最大的那一个*/
    //    public default void urlExtensionToRender(String extension, String renderName) {
    //        this.urlExtensionToRender(0, extension, renderName);
    //    }
    //
    //    public void urlExtensionToRender(int index, String extension, String renderName);
}