/* * Copyright 2013- Yan Bonnel * * 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 fr.ybonnel.simpleweb4j.handlers; import fr.ybonnel.simpleweb4j.handlers.websocket.WebSocketWrapper; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.UpgradeResponse; import org.eclipse.jetty.websocket.server.WebSocketHandler; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Handler for websocket. */ public class SimpleWeb4JWSHandler extends WebSocketHandler implements WebSocketCreator { /** * All routes. */ private List<WebSocketRoute> routes = new ArrayList<>(); /** * Configure the factory. * * @param factory the factory to configure. */ @Override public void configure(WebSocketServletFactory factory) { factory.setCreator(this); } /** * Add a route to handler. * * @param route route to add. */ public void addRoute(WebSocketRoute route) { routes.add(route); } /** * Handle a request. * * @param target The target of the request - either a URI or a name. * @param baseRequest The original unwrapped request object. * @param request The request either as the {@link Request} * object or a wrapper of that request. * @param response The response as the {@link org.eclipse.jetty.server.Response} * object or a wrapper of that request. * @throws IOException in case of IO error. * @throws ServletException in case of IO error. */ @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { if (baseRequest.isHandled()) { return; } WebSocketRoute<?, ?> route = findRoute(request.getPathInfo()); if (route != null) { super.handle(target, baseRequest, request, response); } } /** * Create the WebSocketWrapper. * * @param req the request. * @param resp the response. * @return the WebSocketWrapper created. */ @Override @SuppressWarnings("unchecked") public WebSocketWrapper<?, ?> createWebSocket(UpgradeRequest req, UpgradeResponse resp) { WebSocketRoute route = findRoute(req.getRequestURI().toASCIIString()); if (route != null) { RouteParameters parameters = new RouteParameters( route.getRouteParams(req.getRequestURI().toASCIIString(), getQueryParameters(req))); return new WebSocketWrapper(route.getAdapter().createListenner(parameters)); } return null; } /** * Get parameters from query. * * @param request the request. * @return map of query parameters. */ private Map<String, String> getQueryParameters(UpgradeRequest request) { Map<String, String> queryParameters = new HashMap<>(); for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) { queryParameters.put(entry.getKey(), entry.getValue()[0]); } return queryParameters; } /** * Find a route for method and path. * * @param pathInfo path. * @return the route found (null if no route found). */ protected WebSocketRoute<?, ?> findRoute(String pathInfo) { for (WebSocketRoute route : routes) { if (route.isThisPath(pathInfo)) { return route; } } return null; } }