001package org.tynamo.resteasy;
002
003import org.apache.tapestry5.ioc.annotations.Inject;
004import org.apache.tapestry5.ioc.annotations.Symbol;
005import org.apache.tapestry5.services.ApplicationGlobals;
006import org.apache.tapestry5.services.HttpServletRequestFilter;
007import org.apache.tapestry5.services.HttpServletRequestHandler;
008import org.jboss.resteasy.core.ResourceMethodRegistry;
009import org.jboss.resteasy.jsapi.JSAPIWriter;
010import org.jboss.resteasy.jsapi.ServiceRegistry;
011import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;
012import org.jboss.resteasy.spi.ResteasyDeployment;
013import org.jboss.resteasy.spi.ResteasyProviderFactory;
014import org.slf4j.Logger;
015
016import javax.servlet.http.HttpServletRequest;
017import javax.servlet.http.HttpServletResponse;
018import java.io.IOException;
019import java.util.HashMap;
020import java.util.Map;
021import java.util.regex.Pattern;
022
023public class JSAPIRequestFilter implements HttpServletRequestFilter
024{
025
026        private final Logger logger;
027        private final Pattern filterPattern;
028        private final JSAPIWriter apiWriter = new JSAPIWriter();
029        private Map<String, ServiceRegistry> services;
030
031        public JSAPIRequestFilter(@Inject @Symbol(ResteasySymbols.MAPPING_PREFIX_JSAPI) String filterPath,
032                                  ApplicationGlobals globals, Logger logger)
033                        throws Exception
034        {
035                this.logger = logger;
036
037                this.filterPattern = Pattern.compile(filterPath + ".*", Pattern.CASE_INSENSITIVE);
038
039                Map<String, ResteasyDeployment> deployments = (Map<String, ResteasyDeployment>) globals.getServletContext().getAttribute(ResteasyContextParameters.RESTEASY_DEPLOYMENTS);
040
041                if (deployments != null)
042                {
043                        services = new HashMap<String, ServiceRegistry>();
044                        for (Map.Entry<String, ResteasyDeployment> entry : deployments.entrySet())
045                        {
046                                ResourceMethodRegistry registry = (ResourceMethodRegistry) entry.getValue().getRegistry();
047                                ResteasyProviderFactory providerFactory = entry.getValue().getProviderFactory();
048                                ServiceRegistry service = new ServiceRegistry(null, registry, providerFactory, null);
049                                services.put(entry.getKey(), service);
050                        }
051                }
052        }
053
054        @Override
055        public boolean service(HttpServletRequest request, HttpServletResponse response, HttpServletRequestHandler handler) throws IOException
056        {
057                String path = request.getServletPath();
058                String pathInfo = request.getPathInfo();
059                if (pathInfo != null)
060                        path += pathInfo;
061
062                if (filterPattern.matcher(path).matches())
063                {
064                        String uri = request.getRequestURL().toString();
065                        uri = uri.substring(0, uri.length() - request.getServletPath().length());
066                        if (logger.isDebugEnabled())
067                        {
068                                logger.debug("Serving " + pathInfo);
069                                logger.debug("Query " + request.getQueryString());
070                        }
071                        if (this.services == null)
072                        {
073                                response.sendError(503, "There are no Resteasy deployments.");
074                        }
075                        response.setContentType("text/javascript");
076                        this.apiWriter.writeJavaScript(uri, request, response, services);
077                        return true;
078                }
079                return handler.service(request, response);
080        }
081}