Package org.auraframework.http

Source Code of org.auraframework.http.AuraContextFilter

/*
* Copyright (C) 2013 salesforce.com, inc.
*
* 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 org.auraframework.http;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpHeaders;
import org.auraframework.Aura;
import org.auraframework.adapter.ConfigAdapter;
import org.auraframework.def.ApplicationDef;
import org.auraframework.def.BaseComponentDef;
import org.auraframework.def.ComponentDef;
import org.auraframework.def.DefDescriptor;
import org.auraframework.def.DefDescriptor.DefType;
import org.auraframework.def.Definition;
import org.auraframework.def.ThemeDef;
import org.auraframework.http.RequestParam.BooleanParam;
import org.auraframework.http.RequestParam.EnumParam;
import org.auraframework.http.RequestParam.InvalidParamException;
import org.auraframework.http.RequestParam.StringParam;
import org.auraframework.service.DefinitionService;
import org.auraframework.service.LoggingService;
import org.auraframework.system.AuraContext;
import org.auraframework.system.AuraContext.Authentication;
import org.auraframework.system.AuraContext.Format;
import org.auraframework.system.AuraContext.Mode;
import org.auraframework.system.Client;
import org.auraframework.system.MasterDefRegistry;
import org.auraframework.test.Resettable;
import org.auraframework.test.TestContext;
import org.auraframework.test.TestContextAdapter;
import org.auraframework.throwable.AuraRuntimeException;
import org.auraframework.throwable.quickfix.QuickFixException;
import org.auraframework.util.AuraTextUtil;
import org.auraframework.util.json.JsonReader;

import com.google.common.collect.Maps;

public class AuraContextFilter implements Filter {
    private static final boolean isProduction = Aura.getConfigAdapter().isProduction();

    public static final EnumParam<AuraContext.Mode> mode = new EnumParam<AuraContext.Mode>(AuraServlet.AURA_PREFIX
            + "mode", false, AuraContext.Mode.class);

    public static final BooleanParam isDebugToolEnabled = new BooleanParam(AuraServlet.AURA_PREFIX
            + "debugtool", false);

    private static final EnumParam<Format> format = new EnumParam<Format>(AuraServlet.AURA_PREFIX + "format", false,
            Format.class);

    private static final EnumParam<Authentication> access = new EnumParam<Authentication>(AuraServlet.AURA_PREFIX
            + "access", false,
            Authentication.class);

    private static final StringParam app = new StringParam(AuraServlet.AURA_PREFIX + "app", 0, false);
    private static final StringParam num = new StringParam(AuraServlet.AURA_PREFIX + "num", 0, false);
    private static final StringParam test = new StringParam(AuraServlet.AURA_PREFIX + "test", 0, false);
    private static final BooleanParam testReset = new BooleanParam(AuraServlet.AURA_PREFIX + "testReset", false);
    private static final StringParam contextConfig = new StringParam(AuraServlet.AURA_PREFIX + "context", 0, false);

    private String componentDir = null;

    private static final Log LOG = LogFactory.getLog(AuraContextFilter.class);

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException,
            IOException {

        if (Aura.getContextService().isEstablished()) {
            LOG.error("Aura context was not released correctly! New context will NOT be created.");
            chain.doFilter(req, res);
            return;
        }

        LoggingService loggingService = Aura.getLoggingService();
        try {
            startContext(req, res, chain);
            HttpServletRequest request = (HttpServletRequest) req;
            loggingService.setValue(LoggingService.REQUEST_METHOD, request.getMethod());
            loggingService.setValue(LoggingService.AURA_REQUEST_URI, request.getRequestURI());
            loggingService.setValue(LoggingService.AURA_REQUEST_QUERY, request.getQueryString());
            chain.doFilter(req, res);
        } catch (InvalidParamException e) {
            HttpServletResponse response = (HttpServletResponse) res;
            response.setStatus(500);
            Appendable out = response.getWriter();
            out.append(e.getMessage());
            return;
        } finally {
            try {
                if (loggingService != null) {
                    try {
                        loggingService.setValue(LoggingService.STATUS,
                                String.valueOf(((HttpServletResponse) res).getStatus()));
                    } catch (Throwable t) {
                        // ignore.
                    }
                    loggingService.flush(); // flush out logging values
                }
            } finally {
                endContext();
            }
        }
    }

    protected AuraContext startContext(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
            ServletException {
        HttpServletRequest request = (HttpServletRequest) req;

        Format f = format.get(request);
        Authentication a = access.get(request, Authentication.AUTHENTICATED);

        Map<String, Object> configMap = getConfigMap(request);
        Mode m = getMode(request, configMap);
        boolean d = getDebugToolParam(request);

        DefDescriptor<? extends BaseComponentDef> appDesc = getAppParam(request, configMap);

        if (componentDir != null) {
            System.setProperty("aura.componentDir", componentDir);
        }
        //
        // FIXME: our usage of format should be revisited. Most URLs have
        // a fixed format, so we should have a way of getting that.
        //
        if (f == null) {
            if ("GET".equals(request.getMethod())) {
                f = Format.HTML;
            } else {
                f = Format.JSON;
            }
        }
        AuraContext context = Aura.getContextService().startContext(m, f, a, appDesc, d);

        String contextPath = request.getContextPath();
        // some appservers (like tomcat) use "/" as the root path, others ""
        if ("/".equals(contextPath)) {
            contextPath = "";
        }
        context.setContextPath(contextPath);
        context.setNum(num.get(request));
        context.setRequestedLocales(Collections.list(request.getLocales()));
        context.setClient(new Client(request.getHeader(HttpHeaders.USER_AGENT)));
        if (configMap != null) {
            getLoaded(context, configMap.get("loaded"));
            @SuppressWarnings("unchecked")
            List<Object> dns = (List<Object>) configMap.get("dn");
            if (dns != null) {
                for (Object dn : dns) {
                    context.addDynamicNamespace((String) dn);
                }
            }
            context.setFrameworkUID((String) configMap.get("fwuid"));

            @SuppressWarnings("unchecked")
            List<String> themes = (List<String>) configMap.get("themes");
            if (themes != null) {
                try {
                    DefinitionService ds = Aura.getDefinitionService();
                    for (String theme : themes) {
                        context.appendThemeDescriptor(ds.getDefDescriptor(theme, ThemeDef.class));
                    }
                } catch (QuickFixException e) {
                    throw new AuraRuntimeException(e);
                }
            }
        }

        if (!isProduction) {
            TestContextAdapter testContextAdapter = Aura.get(TestContextAdapter.class);
            if (testContextAdapter != null) {
                String testName = null;
                // config takes precedence over param because the value is not expected to change during a test and it
                // is less likely to have been modified unintentionally when from the config
                if (configMap != null) {
                    testName = (String) configMap.get("test");
                }
                if (testName == null) {
                    testName = test.get(request);
                }
                if (testName != null) {
                    TestContext testContext = testContextAdapter.getTestContext(testName);
                    if (testContext != null) {
                        MasterDefRegistry registry = context.getDefRegistry();
                        Set<Definition> mocks = testContext.getLocalDefs();
                        if (mocks != null) {
                            boolean doReset = testReset.get(request);
                            for (Definition def : mocks) {
                                if (doReset && def instanceof Resettable) {
                                    ((Resettable) def).reset();
                                }
                                registry.addLocalDef(def);
                            }
                        }
                    }
                } else {
                    testContextAdapter.clear();
                }
            }
        }

        return context;
    }

    /**
     * Pull in the map of loaded defDescriptors and uids from the context.
     */
    private void getLoaded(AuraContext context, Object loadedEntry) {
        if (loadedEntry == null || !(loadedEntry instanceof Map)) {
            //
            // If someone gives us bogus input, just ignore it.
            //
            return;
        }
        @SuppressWarnings("unchecked")
        Map<String, String> loaded = (Map<String, String>) loadedEntry;
        DefinitionService definitionService = Aura.getDefinitionService();
        Map<DefDescriptor<?>, String> clientLoaded = Maps.newHashMap();

        for (Map.Entry<String, String> entry : loaded.entrySet()) {
            String uid = entry.getValue();
            if (uid != null && !uid.equals("null")) {
                String key = entry.getKey();
                int posn = key.indexOf("@");
                if (posn > 0) {
                    String typeStr = key.substring(0, posn);
                    String defStr = key.substring(posn + 1);
                    DefType type = null;
                    try {
                        type = DefType.valueOf(typeStr);
                    } catch (Throwable t) {
                        // ignore unknown types...
                        // We really should log these at a level where we can
                        // see them, but, well, we don't have that now.
                    }
                    if (type != null) {
                        DefDescriptor<?> ld = null;

                        ld = definitionService.getDefDescriptor(defStr, type.getPrimaryInterface());
                        clientLoaded.put(ld, uid);
                    }
                }
            }
        }
        context.setClientLoaded(clientLoaded);
    }

    @SuppressWarnings("unchecked")
    private Map<String, Object> getConfigMap(HttpServletRequest request) {
        Map<String, Object> configMap = null;
        String config = contextConfig.get(request);
        if (!AuraTextUtil.isNullEmptyOrWhitespace(config)) {
            configMap = (Map<String, Object>) new JsonReader().read(config);
        }
        return configMap;
    }

    private Mode getModeParam(HttpServletRequest request, Map<String, Object> configMap) {
        // Get the passed in mode param.
        // Check the aura.mode param first then fall back to the mode value
        // embedded in the aura.context param
        Mode m = null;
        m = mode.get(request);
        if (m == null && configMap != null && configMap.containsKey("mode")) {
            m = Mode.valueOf((String) configMap.get("mode"));
        }
        return m;
    }

    protected Mode getModeParam(HttpServletRequest request) {
        Map<String, Object> configMap = getConfigMap(request);
        return getModeParam(request, configMap);
    }

    protected Mode getMode(HttpServletRequest request, Map<String, Object> configMap) {
        Mode m = getModeParam(request, configMap);
        ConfigAdapter configAdapter = Aura.getConfigAdapter();
       
        if (m == null) {
            m = configAdapter.getDefaultMode();
        }
        Set<Mode> allowedModes = configAdapter.getAvailableModes();
        boolean forceProdMode = !allowedModes.contains(m) && allowedModes.contains(Mode.PROD);
        if (forceProdMode) {
            m = Mode.PROD;
        }

        return m;
    }

    private DefDescriptor<? extends BaseComponentDef> getAppParam(HttpServletRequest request,
            Map<String, Object> configMap) {
        String appName = null;
        String cmpName = null;

        appName = app.get(request, null);
        if (appName == null && configMap != null) {
            appName = (String) configMap.get("app");
            if (appName == null) {
                cmpName = (String) configMap.get("cmp");
            }
        }
        if (appName != null) {
            return Aura.getDefinitionService().getDefDescriptor(appName, ApplicationDef.class);
        } else if (cmpName != null) {
            return Aura.getDefinitionService().getDefDescriptor(cmpName, ComponentDef.class);
        }
        return null;
    }

    protected Mode getMode(HttpServletRequest request) {
        Map<String, Object> configMap = getConfigMap(request);
        return getMode(request, configMap);
    }

    protected void endContext() {
        Aura.getContextService().endContext();
    }

    protected Boolean getDebugToolParam(HttpServletRequest request) {
        // Get Passed in aura.debugtool param
        return isDebugToolEnabled.get(request);
    }

    @Override
    public void destroy() {
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String dirConfig = filterConfig.getInitParameter("componentDir");
        if (!AuraTextUtil.isNullEmptyOrWhitespace(dirConfig)) {
            componentDir = filterConfig.getServletContext().getRealPath("/") + dirConfig;
        }
    }
}
TOP

Related Classes of org.auraframework.http.AuraContextFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.