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

com.astamuse.asta4d.web.dispatch.RequestDispatcher Maven / Gradle / Ivy

/*
 * Copyright 2012 astamuse company,Ltd.
 * 
 * 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 com.astamuse.asta4d.web.dispatch;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.astamuse.asta4d.Context;
import com.astamuse.asta4d.web.WebApplicationConfiguration;
import com.astamuse.asta4d.web.WebApplicationContext;
import com.astamuse.asta4d.web.dispatch.mapping.UrlMappingResult;
import com.astamuse.asta4d.web.dispatch.mapping.UrlMappingRule;
import com.astamuse.asta4d.web.dispatch.request.ResultTransformerUtil;
import com.astamuse.asta4d.web.dispatch.response.provider.ContentProvider;
import com.astamuse.asta4d.web.dispatch.response.writer.ContentWriter;
import com.astamuse.asta4d.web.dispatch.response.writer.HeaderWriter;
import com.astamuse.asta4d.web.util.DeclareInstanceUtil;
import com.astamuse.asta4d.web.util.RedirectUtil;

public class RequestDispatcher {

    public final static String KEY_CURRENT_RULE = RequestDispatcher.class.getName() + "##KEY_CURRENT_RULE";

    public final static String KEY_REQUEST_HANDLER_RESULT = "RequestDispatcher##KEY_REQUEST_HANDLER_RESULT";

    private final static Logger logger = LoggerFactory.getLogger(RequestDispatcher.class);

    private final static HeaderWriter headerWriter = new HeaderWriter();

    private DispatcherRuleExtractor ruleExtractor;

    private List ruleList;

    public RequestDispatcher() {

    }

    public DispatcherRuleExtractor getRuleExtractor() {
        return ruleExtractor;
    }

    public void setRuleExtractor(DispatcherRuleExtractor ruleExtractor) {
        this.ruleExtractor = ruleExtractor;
    }

    public List getRuleList() {
        return ruleList;
    }

    public void setRuleList(List ruleList) {
        this.ruleList = ruleList;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void dispatchAndProcess(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("access for:" + request.getRequestURI());
        UrlMappingResult result = ruleExtractor.findMappedRule(request, ruleList);

        if (logger.isDebugEnabled()) {
            logger.debug("apply rule at :" + result.getRule());
        }

        // if not found result, we do not need return 404, instead of user
        // defining all match rule
        WebApplicationContext context = (WebApplicationContext) Context.getCurrentThreadContext();
        writePathVarToContext(context, result.getPathVarMap());

        UrlMappingRule rule = result.getRule();
        context.setData(KEY_CURRENT_RULE, rule);
        writePathVarToContext(context, rule.getExtraVarMap());
        retrieveFlashScopeData(request);

        List> requestResult = handleRequest(rule);
        ContentWriter cw;
        for (ContentProvider cp : requestResult) {
            cw = (ContentWriter) DeclareInstanceUtil.createInstance(cp.getContentWriter());
            cw.writeResponse(rule, response, cp.produce());
        }
    }

    /**
     * 
     * @param request
     * @return ContentProvider
     * @throws Exception
     */
    private List> handleRequest(UrlMappingRule currentRule) throws Exception {
        // TODO should we handle the exceptions?
        WebApplicationContext context = (WebApplicationContext) Context.getCurrentThreadContext();
        RequestHandlerInvokerFactory factory = ((WebApplicationConfiguration) context.getConfiguration()).getRequestHandlerInvokerFactory();
        RequestHandlerInvoker invoker = factory.getInvoker();

        Object requestHandlerResult;
        try {
            requestHandlerResult = invoker.invoke(currentRule);
        } catch (InvocationTargetException ex) {
            logger.error(currentRule.toString(), ex);
            requestHandlerResult = ex.getTargetException();
        } catch (Exception ex) {
            logger.error(currentRule.toString(), ex);
            requestHandlerResult = ex;
        }

        context.setData(KEY_REQUEST_HANDLER_RESULT, requestHandlerResult);

        List> cpList = new ArrayList<>();

        if (requestHandlerResult instanceof List) {
            List resultList = (List) requestHandlerResult;
            ContentProvider cp;
            for (Object result : resultList) {
                if (result instanceof ContentProvider) {
                    cpList.add((ContentProvider) result);
                } else {
                    cp = ResultTransformerUtil.transform(requestHandlerResult, currentRule.getResultTransformerList());
                    cpList.add(cp);
                }
            }
        } else {
            ContentProvider cp = ResultTransformerUtil.transform(requestHandlerResult, currentRule.getResultTransformerList());
            cpList.add(cp);
        }
        return cpList;
        /*
                Method m = requestHandlerResult == null ? null : AnnotationMethodHelper.findMethod(requestHandlerResult, ContentProvider.class);
                if (m == null) {
                    List list = currentRule.getContentProviderMap();
                    Class cls;
                    Object instanceIdentifier;
                    ResultDescriptor matchResult = null;
                    for (ResultDescriptor rd : list) {
                        cls = rd.getResultTypeIdentifier();
                        instanceIdentifier = rd.getResultInstanceIdentifier();
                        if (cls == null && instanceIdentifier == null) {
                            // if there is an exception, it should no be matched to the
                            // default rule.
                            if (requestHandlerResult instanceof Exception) {
                                continue;
                            } else {
                                matchResult = rd;
                                break;
                            }
                        } else if (requestHandlerResult == null) {
                            continue;
                        } else if (cls == null) {
                            if (instanceIdentifier.equals(requestHandlerResult)) {
                                matchResult = rd;
                                break;
                            }
                        } else if (cls.isAssignableFrom(requestHandlerResult.getClass())) {
                            matchResult = rd;
                            break;
                        }
                    }
                    if (matchResult == null) {
                        if (requestHandlerResult instanceof Exception) {
                            throw (Exception) requestHandlerResult;
                        } else {
                            throw new NullPointerException("request result should not be null!!![" + currentRule.toString() + "]");
                        }
                    } else {
                        return matchResult;
                    }
                } else {
                    ContentProvider cp = m.getAnnotation(ContentProvider.class);
                    ContentWriter cw = cp.writer().newInstance();
                    return new ResultDescriptor(requestHandlerResult, requestHandlerResult, cw);
                }
        */
    }

    private void writePathVarToContext(WebApplicationContext context, Map pathVarMap) {
        Iterator> it = pathVarMap.entrySet().iterator();
        Entry entry;
        while (it.hasNext()) {
            entry = it.next();
            context.setData(WebApplicationContext.SCOPE_PATHVAR, entry.getKey(), entry.getValue());
        }
    }

    private void retrieveFlashScopeData(HttpServletRequest request) {
        String flashScopeId = request.getParameter(RedirectUtil.KEY_FLASH_SCOPE_ID);
        if (StringUtils.isEmpty(flashScopeId)) {
            return;
        }
        RedirectUtil.getFlashScopeData(flashScopeId);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy