Package restx.servlet

Source Code of restx.servlet.RestxMainRouterServlet

package restx.servlet;

import com.google.common.base.Optional;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.janino.ExpressionEvaluator;
import org.codehaus.janino.JaninoRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import restx.RestxMainRouterFactory;
import restx.factory.Factory;
import restx.server.WebServer;
import restx.server.WebServers;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Set;

public class RestxMainRouterServlet extends AbstractRestxMainRouterServlet {
    public static final String DEPLOYED_SERVER_ID = "SERVLET-ENGINE-1";

    private static final Logger logger = LoggerFactory.getLogger(RestxMainRouterServlet.class);
    private String serverId;

    public RestxMainRouterServlet() {
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);

        Optional<String> baseUri = Optional.fromNullable(System.getProperty("restx.baseUri"));
        String baseServer = config.getServletContext().getInitParameter("restx.baseServerUri");
        if (!baseUri.isPresent() && baseServer != null) {
            try {
                // try to use servlet3 API without actually requiring it
                Collection<String> mappings = getMappings(config);
                if (!mappings.isEmpty()) {
                    String routerPath = mappings.iterator().next();
                    if (routerPath.endsWith("/*")) {
                        routerPath = routerPath.substring(0, routerPath.length() - 2);
                    }
                    baseUri = Optional.of(baseServer + routerPath);
                    logger.debug("deduced baseUri from servlet registration: {}", baseUri);
                }
            } catch (JaninoRuntimeException e) {
                logger.info("servlet <3 detected. use servlet3+ to get automatic baseUri detection");
            } catch (CompileException e) {
                logger.info("servlet <3 detected. use servlet3+ to get automatic baseUri detection");
            } catch (InvocationTargetException e) {
                logger.info("servlet <3 detected. use servlet3+ to get automatic baseUri detection");
            }
        }
        if (!baseUri.isPresent()) {
            logger.info("MINOR: baseUri cannot be found. Define it in restx.baseUri system property, or use Servlet 3+ API\n" +
                    "Note that is has no effect on restx behavior, it's just that it won't be able" +
                    " to properly display the startup banner.");
        }

        serverId = Optional.fromNullable(
                config.getServletContext().getInitParameter("restx.serverId"))
                .or(DEPLOYED_SERVER_ID);

        registerIdNeeded(serverId);

        init(RestxMainRouterFactory.newInstance(serverId, baseUri));
    }

    @SuppressWarnings("unchecked")
    protected Collection<String> getMappings(ServletConfig config) throws CompileException, InvocationTargetException {
        ExpressionEvaluator expressionEvaluator = new ExpressionEvaluator(
                "config.getServletContext().getServletRegistration(config.getServletName()).getMappings()",
                Collection.class,
                new String[]{"config"},
                new Class[]{ServletConfig.class});
        return (Collection<String>) expressionEvaluator.evaluate(new Object[]{config});
    }

    @Override
    public void destroy() {
        super.destroy();

        if (serverId != null) {
            RestxMainRouterFactory.clear(serverId);
        }
    }

    private static synchronized void registerIdNeeded(String serverId) {
        Optional<WebServer> serverById = WebServers.getServerById(serverId);
        if (!serverById.isPresent()) {
            WebServers.register(new DeployedWebServer(serverId, guessServerType()));
        }
    }

    /**
     * Tries to guess server type based on current callstack.
     *
     * It uses the set of registered server types to make the guess, so this can be contributed through plugins.
     *
     * @return the guessed server type, may be 'unknown'
     */
    private static String guessServerType() {
        try {
            Set<RegisteredServerType> serverTypes = Factory.getInstance().getComponents(RegisteredServerType.class);
            for (StackTraceElement stackTraceElement : new Exception().fillInStackTrace().getStackTrace()) {
                for (RegisteredServerType registeredServerType : serverTypes) {
                    if (stackTraceElement.getClassName().startsWith(registeredServerType.getPackageName())) {
                        return registeredServerType.getServerType();
                    }
                }
            }
            return "unknown";
        } catch (Exception ex) {
            return "unknown";
        }
    }

    private static class DeployedWebServer implements WebServer {
        private final String serverId;
        private final String serverType;

        private DeployedWebServer(String serverId, String serverType) {
            this.serverId = serverId;
            this.serverType = serverType;
        }

        @Override
        public void start() throws Exception {
            throw new UnsupportedOperationException();
        }

        @Override
        public void startAndAwait() throws Exception {
            throw new UnsupportedOperationException();
        }

        @Override
        public void await() throws Exception {
            throw new UnsupportedOperationException();
        }

        @Override
        public void stop() throws Exception {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean isStarted() {
            return true;
        }

        @Override
        public String baseUrl() {
            return System.getProperty("restx.server.baseUrl", "");
        }

        @Override
        public String getServerId() {
            return serverId;
        }

        @Override
        public int getPort() {
            return 0;
        }

        @Override
        public String getServerType() {
            return serverType;
        }
    }

}
TOP

Related Classes of restx.servlet.RestxMainRouterServlet

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.